How to find a specific number in a string Java - java

I am trying to figure out how to search a string for a certain number then if that number exists in the string do the following:
String str = "String4";
int myInt = 0;
public static void checkString(String str) // FIX ME
{
if(str.indexOf('3') == 0)
{
myInt = 3;
}
else if(str.indexOf('4') == 0)
{
myInt = 4;
}
else if(str.indexOf('5') == 0)
{
myInt = 5;
}
}
This never returns true though, is there an alternative way to search the string. There is a lot of extra code, but this method is the only thing causing the problem. I am pulling my hair out because of it, some help would be much appreciated!

For example
if(str.indexOf('3') == 0)
search everytime 3 at position 0, it's not appropriate, because digit can be everywhere in string.
Use instead
str.indexOf('3')!=-1
and retrieve position with return value of indexOf

Check if a substring is in the given string using the contains method.
public static void checkString(String str)
{
if(str.contains("3"))
myInt = 3;
else if(str.contains("4"))
myInt = 4;
else if(str.contains("5"))
myInt = 5;
}

Let's start with an explanation of your approach before we get to an answer.
Starting with your string String str = "String4", I'm assuming that you pass it to checkString().
The indexOf() function for a string searches the string for a substring (a character in your case) and returns its position, indexed from 0. For example, if you call str.indexOf("t") it will return 1 because the character t is in position 1. Therefore, in your code you check if the numbers 3, 4, and 5 reside in the strings index 0 (the first character).
If you want to use indexOf() for this function, you can check if the number is in the string in the first place. IndexOf() returns -1 if the character your searching for isn't in the string, so you can use the following:
if (str.indexOf("3") != -1){
//do your stuff
}
And the same for 4 and 5.

Related

How do I count the parentheses in a string?

This is my method to count the number of parentheses in a string.
public int checkParenthesis(String print, char par){
int num = 0;
for(int i = 0; i<print.length(); i++){
if(print.indexOf(i) == par){
num++;
}
}
return num;
}
It doesn't work. It returns 0.
print is a random string and par is a parenthesis.
You need to use .charAt to get the current character and compare it with par:
if(print.charAt(i) == par)
Another way to do this:
for(char c : print.toCharArray()) {
if(c == par) {
num++;
}
}
You meant charAt instead of indexOf.
The difference is that charAt takes a position in the string (0, 1, ...) and returns the character at that position. indexOf takes a character, and searches the string for the first position where that character is found. You're passing an int to indexOf, not a char, but the compiler accepts this "thanks" to implicit conversions.
In java indexOf is used for checking ch at index. Instead of indexOf u can use string.charAt(index) to get desired result.
public int checkParenthesis(String print, char par){
int num = 0;
for(int i = 0; i<print.length(); i++){
if(print.charAt(i) == par){
num++;
}
}
return num;
}
As others have pointed out, your current algorithm is examining characters at each index with a loop. That would be appropriate with String.charAt(int) but not String.indexOf(int). However, you could certainly implement it with String.indexOf(int, int). Also, I prefer to check for null and an empty input preemptively. Finally, your method counts matching characters (not "checking parenthesis") and doesn't depend on class state so I would make it static. Something like,
public static int countChar(String print, char par) {
if (print == null || print.isEmpty()) {
return 0;
}
int num = 0;
int pos = -1;
while ((pos = print.indexOf(par, pos + 1)) != -1) {
num++;
}
return num;
}
Since Java 9 you can use String#codePoints method:
static long characterCount(String str, char ch) {
// filter the desired characters and return their quantity
return str.codePoints().filter(cp -> cp == ch).count();
}
public static void main(String[] args) {
System.out.println(characterCount("srting))", ')')); // 2
System.out.println(characterCount("{srting}", '{')); // 1
System.out.println(characterCount("(srting)", 's')); // 1
System.out.println(characterCount("[srting]", 'ё')); // 0
}
See also: Recursive method that returns true if the integer exists only once in an array
Just one another way, but with creating extra String objects:
int cnt=print.length()-print.replaceAll(String.valueOf(c),"").length();

Moving from one base to another java?

I'm trying to create a program that reads in two bases from stdin and checks to see what's the smallest number in which both have repeating digits in it. It seems to be working fine for small bases but when I use larger bases I seem to be getting the wrong answer. e.g. giving it 3 and 50 it will find 22 as the smallest number where they both have repeated digits but i'm pretty sure 22 in base 50 is a single number.
What's the logic here that I'm missing? I'm stumped. Anything to point me in the right direction would be appreciated :)
My conversion method, this works for smaller bases but not larger it seems.
public static String converties(int number, int base)
{
int remainder;
ArrayList<Integer>remainders = new ArrayList<Integer>();
while (number != 0)
{
remainder = number%base;
remainders.add(remainder);
number = number/base;
}
String result = "";
for (int i = 0; i < remainders.size(); i++)
{
result+=Integer.toString(remainders.get(i));
}
result = reverseString(result);
return result;
}
public static String reverseString(String result)
{
String newResult = "";
for (int i = result.length()-1; i >= 0; i--)
{
newResult+=result.charAt(i);
}
return newResult;
}
public static boolean areThereRepeats(String value)
{
ArrayList<Character> splitString = new ArrayList<Character>();
for (char c : value.toCharArray())
{
//if it already contains value then theres repeated digit
if (splitString.contains(c))
{
return true;
}
splitString.add(c);
}
return false;
}
The problem is in this function:
public static boolean areThereRepeats(String value){
ArrayList<Character> splitString = new ArrayList<Character>();
for (char c : value.toCharArray()){
//if it already contains value then theres repeated digit
if (splitString.contains(c)){
return true;//Note that returning here only checks the first value that matches
}
splitString.add(c);
}
return false;
}
When you check to see if splitString.contains(c) it will return true if the array is length one. You aren't doing anything to check that the char c you're checking isn't comparing against itself.
Also note that Maraca has a point: the data structure you're choosing to utilize to record your remainders is flawed. areThereRepeats will work fine for checking if you assume that each new character represents a new remainder (or more specifically, the index into the base you're checking of the remainder you found). But why marshal all of that into a string in the first place? Why not pass the ArrayList to areThereRepeats?
public static boolean converties(int number, int base){
int remainder;
ArrayList<Integer>remainders = new ArrayList<Integer>();
while (number != 0){
remainder = number%base;
remainders.add(remainder);//Saves the index of the remainder in the current base, using an integer base-10 representation
number = number/base;
}
return areThereRepeats(remainders);
}
//Recursion ain't efficient, but...
public static boolean areThereRepeats(ArrayList<Integer> remainders){
if (remainders.size() <= 1) {
return false;
}
rSublist = remainders.sublist(1, remainders.size())
if (rSublist.contains(remainders.get(0)) {
return true;
}
return areThereRepeats(rSublist);
}
result+=Integer.toString(remainders.get(i));
In this line you add the remainder in base 10, so it will only work correctly if you find a match with base <= 10. Btw. It could be done very easily with BigInteger (if you don't want to do it yourself).
Otherwise:
result += (char)(remainders.get(i) < 10 ? ('0' + remainders.get(i)) : ('A' + remainders.get(i) - 10));
This will work up to base 36.
Or just use result += (char)remainders.get(i); it will work up to base 256, but it won't be readable.
And I agree with Nathaniel Ford, it would be better to pass the ArrayLists. If you still want to get the String in the standard way you can make another function to which you pass the ArrayList and transform it with the 1st method shown here.

Java: Determining if a word contains letters that can be found in another word?

For example:
If you have a String "magikarp", and you tested it against "karma", this would be true, because all of the letters that make up "karma" can be found in "magikarp".
"kipp" would return false, because there is only one "p" in "magikarp."
This is the attempt that I have right now, but I don't think it's very efficient, and it doesn't return correctly for cases when there are multiple occurrences of one letter.
private boolean containsHelper(String word, String word2){
for (int i = 0; i < word2.length(); i ++){
if (!word.contains(String.valueOf(word2.charAt(i)))){
return false;
}
}
return true;
}
I don't write the program here, but let you know how to do. There are 2 ways to do this considering complexity:
1) If you are sure that you would be getting only a-z/A-Z characters in the string, then take a array of size 26. Loop thorough the first string and place the count of the character appeared in the respective index. Say for example you have String "aabcc". Now array would look like [2,1,2,0,...0]. Now loop through the second String, and at each character, subtract the 1 from the array at the respective character position and check the resultant value. If value is less than 0, then return false. For example you have "aacd". When you are at d, you would be doing (0-1), resulting -1 which is less than 0, hence return false.
2) Sort the characters in the each String, and then compare.
Since you are only checking for characters, it would be more efficient to use indexOf and to check if it return -1 as contains itself call indexOf but with some other trims...
However, I think it would be simplier to convert the String to an array of char and to remove them if they are found which would also handle the case of multiple occurences.
So you're algorithm woud look something like this :
private final boolean containsHelper(final String word, final String word2)
{
char[] secondWordAsCharArray = word2.toCharArray();
char[] firstWordAsCharArray = word.toCharArray();
Arrays.sort(firstWordAsCharArray);//Make sure to sort so we can use binary search.
int index = 0;
for(int i = 0; i++ < secondWordAsCharArray.length;)
{
index = Arrays.binarySearch(firstWordAsCharArray, secondWordAsCharArray[i]);//Binary search is a very performant search algorithm
if(index == -1)
return false;
else
firstWordAsCharArray[index] = ''; //A SENTINEL value, set the char a value you are sure that will never be in word2.
}
}
Basically, what I do is :
Convert both word to char array to make it easier.
Sort the char array of the word we inspect so we can use binary search.
Loop over all characters of the second word.
retrieve the index using the binary search algorithm (a very performant algorithm on char, the best from my knowledge).
if index is -1, it was not found so we can return false.
else make sure we unset the character.
You need to ensure that for any character c that appears in the second string, the number of times that c appears in the second string is no greater than the number of times that c appears in the first string.
One efficient way to tackle this is to use a hashmap to store the count of the characters of the first string, and then loop through the characters in the second string to check whether their total count is no greater than that in the first string. The time and space complexity are O(n) in the worst case, where n is the length of the input strings.
Here is the sample code for your reference:
import java.util.HashMap;
import java.util.Map;
public class HashExample {
public static void main(String[] args) {
System.out.println(containsHelper("magikarp", "karma")); // true
System.out.println(containsHelper("magikarp", "kipp")); // false
}
private static boolean containsHelper(String word, String word2) {
Map<Character, Integer> hm = new HashMap<>();
for (int i = 0; i < word.length(); i++) {
Character key = word.charAt(i);
int count = 0;
if (hm.containsKey(key)) {
count = hm.get(key);
}
hm.put(key, ++count);
}
for (int i = 0; i < word2.length(); i++) {
Character key = word2.charAt(i);
if (hm.containsKey(key)) {
int count = hm.get(key);
if (count > 0) {
hm.put(key, --count);
} else {
return false;
}
} else {
return false;
}
}
return true;
}
}
On possible algorithm is to remove all letters from your second word that don't occur in the first, sort both and then compare them.
Here is a reasonable way to achieve that in Java 8:
List<Integer> wordChars = word.chars().sorted().collect(Collectors.toList());
List<Integer> searchChars = search.chars()
.filter(wordChars::contains).sorted().collect(Collectors.toList());
return wordChars.equals(searchChars);

Return word specified by the integer

I know I'm missing some things and that's what I really need help with. The code doesn't work in all cases and am looking for help improving/fixing it.
Assignment:
The code I have so far:
public String word(int num, String words)
{
int l = words.indexOf(" ");
int r = words.indexOf(" ", l+1);
for(int i = 3; i <= num; i++){
l = r;
r = words.indexOf(" ", l+1);
//if(i != num)
// l = r;
}
String theword = words.substring(l,r);
return theword;
}
}
As this is clearly homework, I will give you text only.
Your approach may work eventually, but it is laborious and overly complicated, so it's hard to debug and hard to get right.
make use of String's API by using the split() method
after splitting the sentence into an array of word Strings, return the element at num less one (array are indexed starting at zero
check the length of the array first, in case there are less words than num, and take whatever action you think is appropriate in that case
For part 2, a solution in a simple form may be:
create a new blank string for the result
iterate over the characters of the given string adding the character to the front of the result string
make use of String's toUpperCase() method
Since this is homework and you have showed some effort. This is how you can do part 1 of your question. This code is pretty evident.
1) I am returning null if number is greater than the number of words in string as we dont want user to enter 5 when there are only 2 words in a string
2) Splitting the string by space and basically returning the array with the number mentioned by user
There are more conditions which you must figure out such as telling the user to enter a number of the string length since it would not give him any result and taking input from Scanner instead of directy adding input in method.
public static String word(int num, String words)
{
String wordsArr[] = words.split(" ");
if(num <= 0 || num > wordsArr.length) return null;
return (wordsArr[num-1]);
}
the second part of your question must be attempted by you.
Well... not often you see people coming here with homework AND showing effort at the same time so bravo :).
This is example of how you can split the string and return the [x] element from that string
public class SO {
public static void main(String[] args) throws Exception {
int number = 3;
String word = "Hello this is sample code";
SO words = new SO();
words.returnWord(number, word);
}
private void returnWord(int number, String word) throws Exception {
String[] words = word.split("\\s+");
int numberOfWords = words.length;
if(numberOfWords >= number) {
System.out.println(words[number-1]);
} else {
throw new Exception("Not enought words!!!");
}
}
}
Yes it is a working example but do not just copy and paste that for your homework - as simple question from teacher - What is this doing, or how this works and your out :)! So understand the code, and try to modify it in a way that you are familiar what is doing what. Also its worth getting some Java book - and i recommend Head first Java by O'Really <- v.good beginner book!
if you have any questions please do ask!. Note that this answer is not 100% with what the textbook is asking for, so you can modify this code accordingly.
As of part 2. Well what Bohemian said will also do, but there is a lot quicker solution to this.
Look at StringBuilder(); there is a method on it that will be of your interest.
To convert String so all letter are upper case you can use .toUpperCase() method on this reversed string :)
You can try:
public class trial {
public static void main(String[] args)
{
System.out.println(specificword(0, "yours faithfully kyobe"));
System.out.println(reverseString("derrick"));}
public static String specificword(int number, String word){
//split by space
String [] parts = word.split("\\ ");
if(number <= parts.length){
return parts[number];
}
else{
return "null String";
}
}
public static String reverseString(String n){
String c ="";
for(int i = n.length()-1; i>=0; i--){
char m = n.charAt(i);
c = c + m;
}
String m = c.toUpperCase();
return m;
}
}
For the first problem, I'll give you two approaches (1. is recommended):
Use the String.split method to split the words up into an array of words, where each element is a word. Instead of one string containing all of the words, such as "hello my name is Michael", it will create an array of the words, like so [hello, my, name, is, Michael] and that way you can use the array to access the words. Very easy:
public static String word(int num, String words)
{
// split words string into array by the spaces
String[] wordArray = words.split(" "); // or = words.split("\\s+");
// if the number is within the range
if (num > 0 && num <= wordArray.length) {
return wordArray[num - 1]; // return the word from the word array
} else { // the number is not within the range of words
return null;
}
}
Only use this if you cannot use arrays! Loop through the word until you have found enough spaces to match the word you want to find:
public static String word(int num, String words)
{
for (int i = 0; i < words.length(); i++) { // every character in words
if (words.substring(i, i+1).equals(" ")) { // if word is a space
num = num - 1; // you've found the next word, so subtract 1 (number of words left is remaining)
}
if (num == 1) { // found all words
// return this word
int lastIndex = i+1;
while (lastIndex < words.length()) { // until end of words string
if (words.substring(lastIndex, lastIndex+1).equals(" ")) {
break;
}
lastIndex = lastIndex + 1; // not a space so keep moving along the word
}
/*
// or you could use this to find the last index:
int lastIndex = words.indexOf(" ", i + 1); // next space after i+1
if (lastIndex == -1) { // couldn't find another space
lastIndex = words.length(); // so just make it the last letter in words
}*/
if (words.substring(i, i+1).equals(" ")) { // not the first word
return words.substring(i+1, lastIndex);
} else {
return words.substring(i, lastIndex);
}
}
}
return null; // didn't find word
}
As for the second problem, just iterate backwards through the string and add each letter to a new string. You add each letter from the original string to a new string, but just back to front. And you can use String.toUpperCase() to convert the string to upper case. Something like this:
public static String reverse(String str) {
String reversedString = ""; // this will be the reversed string
// for every character started at the END of the string
for (int i = str.length() - 1; i > -1; i--) {
// add it to the reverse string
reversedString += str.substring(i, i+1);
}
return reversedString.toUpperCase(); // return it in upper case
}

Get the last three chars from any string - Java

I'm trying to take the last three chracters of any string and save it as another String variable. I'm having some tough time with my thought process.
String word = "onetwotwoone"
int length = word.length();
String new_word = id.getChars(length-3, length, buffer, index);
I don't know how to use the getChars method when it comes to buffer or index. Eclipse is making me have those in there. Any suggestions?
Why not just String substr = word.substring(word.length() - 3)?
Update
Please make sure you check that the String is at least 3 characters long before calling substring():
if (word.length() == 3) {
return word;
} else if (word.length() > 3) {
return word.substring(word.length() - 3);
} else {
// whatever is appropriate in this case
throw new IllegalArgumentException("word has fewer than 3 characters!");
}
I would consider right method from StringUtils class from Apache Commons Lang:
http://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/StringUtils.html#right(java.lang.String,%20int)
It is safe. You will not get NullPointerException or StringIndexOutOfBoundsException.
Example usage:
StringUtils.right("abcdef", 3)
You can find more examples under the above link.
Here's some terse code that does the job using regex:
String last3 = str.replaceAll(".*?(.?.?.?)?$", "$1");
This code returns up to 3; if there are less than 3 it just returns the string.
This is how to do it safely without regex in one line:
String last3 = str == null || str.length() < 3 ?
str : str.substring(str.length() - 3);
By "safely", I mean without throwing an exception if the string is nulls or shorter than 3 characters (all the other answers are not "safe").
The above code is identical in effect to this code, if you prefer a more verbose, but potentially easier-to-read form:
String last3;
if (str == null || str.length() < 3) {
last3 = str;
} else {
last3 = str.substring(str.length() - 3);
}
String newString = originalString.substring(originalString.length()-3);
public String getLastThree(String myString) {
if(myString.length() > 3)
return myString.substring(myString.length()-3);
else
return myString;
}
If you want the String composed of the last three characters, you can use substring(int):
String new_word = word.substring(word.length() - 3);
If you actually want them as a character array, you should write
char[] buffer = new char[3];
int length = word.length();
word.getChars(length - 3, length, buffer, 0);
The first two arguments to getChars denote the portion of the string you want to extract. The third argument is the array into which that portion will be put. And the last argument gives the position in the buffer where the operation starts.
If the string has less than three characters, you'll get an exception in either of the above cases, so you might want to check for that.
Here is a method I use to get the last xx of a string:
public static String takeLast(String value, int count) {
if (value == null || value.trim().length() == 0 || count < 1) {
return "";
}
if (value.length() > count) {
return value.substring(value.length() - count);
} else {
return value;
}
}
Then use it like so:
String testStr = "this is a test string";
String last1 = takeLast(testStr, 1); //Output: g
String last4 = takeLast(testStr, 4); //Output: ring
This method would be helpful :
String rightPart(String text,int length)
{
if (text.length()<length) return text;
String raw = "";
for (int i = 1; i <= length; i++) {
raw += text.toCharArray()[text.length()-i];
}
return new StringBuilder(raw).reverse().toString();
}
The getChars string method does not return a value, instead it dumps its result into your buffer (or destination) array. The index parameter describes the start offset in your destination array.
Try this link for a more verbose description of the getChars method.
I agree with the others on this, I think substring would be a better way to handle what you're trying to accomplish.
You can use a substring
String word = "onetwotwoone"
int lenght = word.length(); //Note this should be function.
String numbers = word.substring(word.length() - 3);
Alternative way for "insufficient string length or null" save:
String numbers = defaultValue();
try{
numbers = word.substring(word.length() - 3);
} catch(Exception e) {
System.out.println("Insufficient String length");
}
This method will return the x amount of characters from the end.
public static String lastXChars(String v, int x) {
return v.length() <= x ? v : v.substring(v.length() - x);
}
//usage
System.out.println(lastXChars("stackoverflow", 4)); // flow

Categories

Resources