So let's say I have an array called arr with the values &&&&.&&. I want to find the number of ampersands (&) that are after the decimal point and store the value into numDecimalDigits.
int numDecimalDigits = 0;
char[] arr = new char[7]
for (int i = 0; i < str.length(); i ++)
{
for (int decimal = (arr[pos] = '.'); decimal <= arr.length; decimal ++)
{
numDecimalDigits += 1;
}
}
I'm not sure if this is the right approach. So the outside for loop runs through each index value of the array. The inner for loop starts at the decimal, and ends at the end of the array. Every time a new value is found, numDecimalDigits is added by one. However, in my code I think numDecimalDigits is returning an incorrect value.
You only need one loop:
boolean foundDot = false;
for (int i = 0; i < arr.length; i++) {
if(arr[i] == '.') {
foundDot = true;
} else if(foundDot) {
numDecimalDigits ++;
}
}
No need to use array. It would be easy like this:(Assuming str value must contains one '.' )
int numDecimalDigits = str.split("\\.")[1].length();
Or you can do by subtracting str.length()-1 with indexOf(".")
int numDecimalDigits = str.length()-1 - str.indexOf(".");
Related
This question already has answers here:
How to replace multiple consecutive occurrences of a character with a maximum allowed number of occurences?
(2 answers)
Closed 3 years ago.
I need to write a method that takes a String as a parameter and returns a new String obtained by replacing every instance of repeated adjacent letters with a 'n' instances of that string.
For example, if "aaabcccd" as an input String and n =2, it returns "aabccd". I already tried the following code, but not getting expected output
String in = "aaadbbb";
char[] s = in.toCharArray();
int len = s.length;
int n = 2;
StringBuffer new_s = new StringBuffer("");
int count = 1;
char prev='\0';
for (int i = 0; i < len - 1; i++) {
if (s[i] == s[i + 1]) {
if(count <= n){
new_s.append(s[i]);
count++;
}else{
count=1;
}
} else {
new_s.append(s[i]);
}
}
System.out.println(new_s);
output-aaadb
expected-aadbb
Can be done with regexp magic using backreferences.
String in = "aaaaddbbbbc";
int n = 2;
String pattern = String.format("(([a-z])\\2{%d})\\2+", n - 1);
System.out.println(in.replaceAll(pattern, "$1"));
Outputs:
aaddbbc
Explanation:
The number inside {} is n-1.
([a-z]) is a capture group, matching any single lowercase letter from a to z. Since it's a second group of parentheses in the expression, it can be referenced as 2.
(([a-z])\\2{n}) means "match n+1 repetitions of same letter". It makes up a first capture group, and we'll use that as replacement
\\2+ matches all the extra repetitions of the same letter. They are discarded after replacement.
public static String test(String input, int repetitions) {
String flag = "";
String replacement = "";
String output = input;
ArrayList<Character> prevLetters = new ArrayList<Character>();
for(int x = 0; x < input.length(); x++) {
if(!prevLetters.contains(input.charAt(x))) {
for(int y = 0; y <= repetitions ; y++) {
flag += String.valueOf(input.charAt(x));
}
if(input.contains(flag)) {
replacement = flag.substring(0, flag.length()-1);
while(output.contains(flag)){
output = output.replace(flag, replacement);
}
}
flag = "";
prevLetters.add(input.charAt(x));
}
}
return output;
}
That is my solution, which follows a similar idea as yours. Rather than comparing each character value however, I thought it would be easier to simply check for a break in the rules (character appearing n+1 times in a row) and 'fix' it.
If you are interested in using your method, one potential issue that I noticed is that you aren't assigning count to 1 in your last else. You also won't have the chance to add the final character due to you only adding the character at index 'i' when the duration for the loop is len - 1.
To add one more alternative:
String in = "aaadbbbjjkllllllopp";
int n = 2;
StringBuilder sb = new StringBuilder();
char temp = in.charAt(0);
for(int i = 0; i < in.length()-1;){ // note that the incrementation of i is moved to the while loop
temp = in.charAt(i); // save current char in temp variable
int count = 0;
while (i < in.length() && in.charAt(i) == temp) { ///iterate as long as you find same chars or hit the end of the string
i++;
count++;
}
if (count > n){ // if and only if count is greater than max allowed set it to max allowed
count = n;
}
for(int j = 0; j < count; j++){ // append count chars
sb.append(temp);
}
}
System.out.println(sb.toString());
Look at this solution. You should take care of the last char in your input string, as you iterate only to the last but one.
private void replaceConsecutiveDuplicates() {
String input = "aaadbbb";
int n = 2;
StringBuffer sb = new StringBuffer();
int count = 1;
char current;
for( int i = 0; i < input.length(); ++i){
current = input.charAt(i);
if (i + 1 < input.length() && current == input.charAt(i + 1)) {
++count;
} else if (count > 1) {
for(int j = 0; j < n; ++j) {
sb.append(current);
}
count = 1;
}
else {
sb.append(current);
}
}
System.out.println(sb.toString());
}
I think you're on the right track. I'm not sure whether this is an assignment, so I don't want to just straight up give you an answer, but here are some hints that might help:
You're already iterating over the string. This is great! However, I think you want to compare the current character with the previous character, and not the next character.
You don't need to convert your input to a char array to iterate over it, just use charAt(idx)
You never seem to use prev, but I think you had the right idea in mind when you declared it!
Break your problem into two parts: When to update count and when to append a character. You can tackle both in your for loop, but instead of trying to do both things in the same if statements, break it up into multiple ifs.
The 3 things to do are:
Update Prev Value
Update Count
Update new String
Getting the right order for these and the exact implementation I'll leave to you (again, because I'm not sure if this is an assignment or not)
Update: Since others posted, here is my solution (with single for loop):
private String replaceConsecutiveDuplicates(String input, int n) {
if (input == null || input.length() < n) return input;
if (n == 0) return "";
StringBuffer sb = new StringBuffer();
int count = 1;
char prev = input.charAt(0);
sb.append(prev);
char current;
for( int i = 1; i < input.length(); i++) {
current = input.charAt(i);
if (prev == current) {
if (++count > n) continue;
} else {
count = 1;
}
prev = current;
sb.append(current);
}
return sb.toString();
}
I am implementing a code for counting number of occurrences for all the characters in a String. I have used indexOf() method to check occurrences. But it's not working for the first character.
The following code works fine for all characters except the first character.
public static void main(String[] args) {
String str = "simultaneously";
int[] count = new int[str.length()]; //counter array
for (int i = 0; i < count.length; i++) { //initializing counters
count[i] = 0;
}
for (int i = 0; i < str.length(); i++) {
int index = -1;
char c = str.charAt(i);
while (1 > 0) {
if (str.indexOf(c,index) > 0) { //This is not working for
//the first characters
index = str.indexOf(c, index) + 1;
count[i]++;
} else {
break;
}
}
}
for (int i = 0; i < count.length; i++) {
System.out.println(str.charAt(i) + " occurs " + count[i] + " times");
}
}
Index for arrays in java starts from 0.
Change the condition from
if (str.indexOf(c,index) > 0) {
to
if (str.indexOf(c,index) >= 0) {
And also, the for-loop to initialize the counter is redundant, by default, all the values in the int array is initialized to 0.
str.indexOf(c,index) would return 0 for the first character, but your condition checks whether str.indexOf(c,index) > 0. Change it to str.indexOf(c,index) >= 0.
There is some thing else you need to know
str.indexOf(c,index)
will search for the character c from the index 'index' which is -1 in your case for the first character that is it will never find this because starting point of string is 0
also change your condition as following
str.indexOf(c,index) >= 0
The index of arrays and Strings (which are array of characters) always start at 0 in Java.
You also want to check position 0, so include >=.
if (str.indexOf(c,index) >= 0) {
Also, using breaks can sometimes be confusing.
In your code, your while-loop is an infinite True and then you break out of it when necessary.
Take a look at this code below. It serves the same purpose that you want to accomplish.
It is much cleaner and clearer as it removes the break from the whileloop and you simply check to see if the statement is True at the beginning of the while-loop rather than inside it.
for (int i = 0; i < str.length(); i++) {
int index = 0;
char c = str.charAt(i);
while (str.indexOf(c,index) >= 0) {
index = str.indexOf(c, index) + 1;
count[i]++;
}
}
OK, i know this question was asked many times here, but i still don't get it, how to find the first repeated character in a string ?
I did something which was close, but it gave me all repeated characters instead of only the first one.
Here's what i did :
private static void stringChar(){
String s = "sababa";
int count = 0;
char c[] = s.toCharArray();
System.out.println("Duplicate characters are :");
for(int i = 0; i < s.length(); i++){
for(int j = i + 1; j < s.length(); j++){
if(c[i] == c[j]) {
System.out.println(c[j]);
count++;
break;
}
}
}
}
One quick and dirty (yet effective) approach which comes to mind is to maintain a map whose keys are the characters. In this case, we don't even need a formal map, because we can use an integer array which maps to the underlying ASCII values of the characters.
The basic idea here is to walk down the string, and check the array if we have seen it before. If so, then print that character and exit.
int[] nums = new int[128]; // assuming only basic ASCII characters
String str = "stuff";
for (int i=0; i < str.length(); ++i) {
int index = str.charAt(i);
if (nums[index] != 0) {
System.out.println("The first repeated character is: " + str.charAt(i));
break;
}
++nums[index];
}
Demo
You need to break the outer loop if you have already found the repeating character.
boolean found = false;
for(int i = 0; i < s.length(); i++){
for(int j = i + 1; j < s.length(); j++){
if(c[i] == c[j]) {
System.out.println(c[j]);
found = true;
break;
}
}
if (found) {
break;
}
}
If you want the count of it
int count = 0;
char repeatingChar = '0'; //dummy to overcome compiler warning
for(int i = 0; i < s.length(); i++){
for(int j = i + 1; j < s.length(); j++){
if(c[i] == c[j]) {
repeatingChar = c[j];
count++;
}
}
if (count > 0) {
System.out.println("Repeating char is " + repeatingChar + ". Occurred " + count + " times");
break;
}
}
The first repeated char is one you have seen before as you iterate the chars in the string. You can keep track of the first time you see a char with a Boolean array. The array is indexed with the char value. Java automatically "widens" char to int. So, for each char, check if it's been seen before and if not, mark that it has been seen.
String s = "sababa";
boolean[] seenChars = new boolean[Character.MAX_VALUE + 1]; // initialized to all false.
for (char c : s.toCharArray()) {
if (Character.isSurrogate(c)) throw new IllegalArgumentException("No first char seen before seeing a surrogate. This algorithm doesn't work for codepoints needing surrogates in UTF-16.");
if (seenChars[c]) {
System.out.println("First repeated char is: " + c);
break;
}
seenChars[c] = true;
}
You might notice that I've been saying char instead of character. Character is not a well-defined term. Java's text datatypes use the UTF-16 encoding of the Unicode character set. Some Unicode codepoints require two UTF-16 code units (char), which are sometimes called surrogate pairs. Since they are not all unique as individual chars, the algorithm doesn't work if they are present. For example, try String s = "sab🚲aba"; (You can also write it as "sab\uD83D\uDEB2aba".) The answer would be "a", again. But now try String s = "sab🚲🚶aba"; (You can also write it as "sab\uD83D\uDEB2\uD83D\uDEB6aba".) The answer should still be "a" but the algorithm would say "\uD83D" (which of course can't be displayed because it is only part of a codepoint).
Short and Simple >
void findFirstDupChar() {
String s = "google";
Integer dupIndex = s.length() - 1;
boolean isDuplicateExists = false;
Map<Character, Integer> map = new LinkedHashMap<>();
char[] words = s.toCharArray();
for (int i = 0; i < words.length; i++) {
Integer index = map.put(words[i], i);
if (index != null) {
if (index < dupIndex) {
dupIndex = index;
isDuplicateExists = true;
}
}
}
System.out.println(isDuplicateExists ? words[dupIndex] + ", index=" + dupIndex : "No duplicateds found");
}
This will print output as following >
g, index=0
I need to input and load some chars in a boolean 2-D array. If the char is X, mark the array element as true; else if the char is ., mark the array element as false.
Here is my design:
boolean[][] Array = new boolean[2][2];
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
if (System.in.read() == '.') {
Array[i][j] = false;
} else if (System.in.read() == 'X') {
Array[i][j] = true;
}
}
}
And, for example, if I type in .... or XXXX, it does not produce the correct result. Also for other input the result is not correct.
So how to deal with this?
You are reading a character a second time in the loop if the first character is not a '.'.
You should only read one character per loop. Save the character in a variable before your if statement, and then compare the variable to '.' and 'X' in turn.
You shouldn't call the read() function in each if statement. Call it one time and store it in a variable so you don't keep reading through the input. That could be one thing messing up your function. Another is how you are comparing chars with the == operator. Should use char.equals method for character comparison. Put a couple breakpoints in and see what values are being sent through to debug. Maybe try something like the following:
boolean[][] Array= new boolean[2][2];
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
Character input = (char)System.in.read();
if (input.equals('.')) {
Array[i][j] = false;
} else if (input.equals('X')) {
Array[i][j] = true;
}
}
}
I have a string
String word = "FrenciusLeonardusNaibaho";
while I'm trying to make matrix like this:
char matriks[][] = new char[16][16];
int k = 0;
for (int i = 1; i < 16; i++) {
for (int j = 1; j < 16; j++) {
matriks[i][j] = word.charAt(k);
k++;
}
}
I got this error
String index out of range: 24
How can I achieve this?
Thanks..
You are overflowing beyond the end of word at word.charAt(k);. Basically you dont have enough alphabets to fill your matrix.
You can do something like this
if(k >= word.length())
break;
Below the inner loop. Or you can init the element to some default value with this condition.
Additionally as others have mentioned, i,j should start at 0, unless you have a good reason to start at 1.
char matriks[][] = new char[16][16];
int k = 0;
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
matriks[i][j] = word.charAt(k%word.length());
k++;
}
}
So it can go from start to end,then restart.
try adding
if(k >= word.length())
k = 0;
to your inner for loop, this will continue filling the array from the beginning of the word.
'Out of bounds' or 'out of range' occures when you try to read or write in an array, list, string or whatever with a range beyond it's boundary. You can't read a a character at index 8 when your string contains only 7 character. It's not your string's RAM and it would cause RAM corruption like it is happening sometimes in C-arrays.
When you set up your array and your for-loop try to check if you are still in bounds of your string with a size or length function of your container. In special case of string it is length.
I think you are trying to split a list of names stored in a string. In such a case it is easier to create a dynamic container, something like list (http://www.easywayserver.com/blog/java-list-example/).
Here I have a little example. For those purposes I prefer a while-loop. In cases I know the length of a list at least at runtime without interpreting data a for-loop is a good choice, but not in this:
String names = "Foo Bar";
List<String> seperatedNames = new List<String>();
String name = "";
int i = 0;
while (i < names.length()) {
if (names.charAt(i) == ' ') { // you can check for upper case char too
seperatedNames.add(name); // add name to list
name = ""; // clear name-buffer
i++; // increment i, else it would produce an infinite loop
}
name += names.charAt(i++); // add current char to name-buffer and increment current char
}
I hope I could help a bit.
of course, you will get this error surely because the character in your word are only 24 character.
to avoid this your need to check the length of your word and need to break the all looping.
Try this code.
char matriks[][] = new char[16][16];
int k = 0;
int lenght = word.length();
outerloop:
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
matriks[i][j] = word.charAt(k);
k++;
if(k >= lenght){
break outerloop;
}
}
}
You are filling 16x16 array and iterating the loop 16x16 times but your word size is less than 16x16. So put a check when k becomes equal to the word length then terminate the loop.Change your code like this.
char matriks[][] = new char[16][16];
int k = 0;
for (int i = 1; i < 16; i++) {
for (int j = 1; j < 16; j++) {
if(k >=word.length)
break;
matriks[i][j] = word.charAt(k);
k++;
}
}