java character converting into number in 2D char array - java

I'm trying to convert all letters in a 2D char array into number. As results, I want a = 0, b=1, c=2, ... z=25.
Then, I tried this as part of my code:
char [][] letters = {{'i', 'u'}, {'a', 'g'}, {'e', 'k'}};
for (int i = 0; i < letters.length; i++) {
for (int j = 0; j < letters[i].length; j++) {
if (letters[i][j] >= 'a' && letters[i][j] <= 'z') {
letters[i][j] = (char) ((letters[i][j] - 'a') + '0');
}
}
}
The result of my code is not what I expected before.
From 'a' to 'j', it worked well. But, from 'k' until 'z' it didn't print expected number.
What's wrong with my code?

First of all you can't store the number 10 as a single char. It is two chars, 1 and 0. So the result array has to be something else than a char array. If it is int your working with then you are probably best of storing them in an int array.
intarray[i][j] = (letters[i][j] - 'a'); where intarray is your array of int values that has the same size as the char array. Other option is to make a string array if you must store the result in the same array and convert it to a number and then into a string. Like this
String [][] letters = {{"i", "u"}, {"a", "g"}, {"e", "k"}};
for (int i = 0; i < letters.length; i++) {
for (int j = 0; j < letters[i].length; j++) {
if (letters[i][j].charAt(0) >= 'a' && letters[i][j].charAt(0) <= 'z') {
letters[i][j] = Integer.toString((letters[i][j].charAt(0) - 'a');
}
}
}
The reason is that the ascii table only has the numbers 0 to 9 as symbols. So in your case you get the first 10 letters to convert but after that you start getting various symbols in the ascii table. k for example would be :, l is ; m is < and so on. When you are working with converting chars to numbers you are better working with them as int as they are easier to do math on.
You could do the same without converting it into an int but that mean you need to find out char - 'a' is bigger than 10. If so you need get the number divided by 10 and then after that the modulo of the number and give each of them the associated ascii symbol to make them into a string. This is a lot more complex and hard to do, specially considering how easy this is by just doing it with ints.
There are 2 other options for you but I still feel the string option above is by far the easiest.
First would be to have the 2d array as an int. You could then initialize the ints to be letters. Then you can do arithmetic on them to find the number they fit. Like this:
int [][] letters = {{'i', 'u'}, {'a', 'g'}, {'e', 'k'}};
for (int i = 0; i < letters.length; i++) {
for (int j = 0; j < letters[i].length; j++) {
if (letters[i][j] >= 'a' && letters[i][j] <= 'z') {
letters[i][j] = (letters[i][j] - 'a');
}
}
}
This would have the same effect. The issue with doing it this way is that printing the actual letter takes a bit more effort and in the end you would need to convert it to a char. So I would not recommend this way.
The second option would be to store everything as the char value in a char array. Like this:
char [][] letters = {{'i', 'u'}, {'a', 'g'}, {'e', 'k'}};
for (int i = 0; i < letters.length; i++) {
for (int j = 0; j < letters[i].length; j++) {
if (letters[i][j] >= 'a' && letters[i][j] <= 'z') {
letters[i][j] = (char) (letters[i][j] - 'a');
}
}
}
To print this then you would need to cast the char to an int. So you could print them with:
for (int i = 0; i < letters.length; i++) {
for (int j = 0; j < letters[i].length; j++) {
System.out.printf("%d\n", (int) letters[i][j]);
}
}
This would then work as well but it is a bit hacky and you need to make sure you cast the char you have to an int all the time. So far I think the string array is the best option but it depends on what your goal is. But one thing that you can't do is store the char '10' in a char array as '10' isn't a single char but 2 chars and don't fit in a char.

Related

Replacing Duplicates in Character Array with placeholder character ' '?

For any string of characters I input to my charArray, this simply returns the first character and the rest as spaces. Why? I simply want to replace all of the non-original renditions of a character with a space.
for (int i = 0 ; i<charArray.length ; i++) {
for (int j = 1 ; j<charArray.length ; j++) {
if (charArray[i] == charArray[j])
charArray[j] = ' ';
}
}
Your inner loop needs to start at i + 1 instead of the hardcoded value 1:
char[] charArray = "abcdabce".toCharArray();
for (int i = 0; i < charArray.length; i++)
{
// check if a space was already inserted at this index
if (charArray[i] == ' ')
continue;
// check all remaining characters
for (int j = i + 1; j < charArray.length; j++)
{
if (charArray[i] == charArray[j])
{
charArray[j] = ' ';
}
}
}
System.out.println(charArray);
Output:
abcd e
To put it simply, this is what your code currently does:
For each character in the char array, if the same character appears somewhere in the array starting from the index 1, then change it to a space. This concretely means that all the characters starting from index 1 will be replaced (because the condition that they appear after index 0 will always be satisfied).
A simple example can illustrate why this won't actually work.
Suppose your input array is ['h','e','l','l','o'].
When i = 1 and j = 1, charArray[i] == charArray[j] will return true, thus your 'e' will be replaced by a space.
I would suggest looping through the array once, using a data structure that memorizes which characters previously appeared, which in this case corresponds to a Set.
Set<Character> charSet = new HashSet<>();
for (int i = 0; i < charArray.length; i ++) {
if (charSet.contains(charArray[i])) charArray[i] = ' ';
else charSet.add(charArray[i]);
}

Skipping empty indexes in a 2d char[][] array when looping the array for a char value and appending it to a String

How do you skip all empty indexes in a 2D char[][] array when looping through it to build a string out of of all the indexes that do have a char value?
In the code below I used \0 to represent the empty indexes and wrote a condition to append all indexes that are not \0 to text. Is this a good way to do it or is there a more efficient method?
StringBuilder text = new StringBuilder();
for (int i = 0; i < row; i++) {
for (int j = 0; j < col.length(); j++) {
if (charArray[i][j] != '\0') {
text.append(charArray[i][j]);
}
}
this.newText = text.toString();
You will need to travel the entire 2D array to find out the empty element.
For traveling a 2D A[m][n] array, the time complexity (best) is O(m*n), which you're using so there isn't any other method that will reduce the time complexity.
There is a difference between '\0' and ' '. `\0' is for null and ' ' is for empty char.
Your use case needs to omit empty char, so use ' '
for (int i = 0; i < row; i++) {
for (int j = 0; j < col.length(); j++) {
if (charArray[i][j] != '') {
text.append(charArray[i][j]);
}
}
this.newText = text.toString();
This would iterate all rows and columns of charArray test value and allows for arrays of different lengths:
char[][]charArray = new char[][] { new char[] {65, '\0', 66 }
, new char[] {68,69, 70, '\0', 71 }};
StringBuilder text = new StringBuilder();
for (int i = 0; i < charArray.length; i++) {
char[] theRow = charArray[i];
for (int j = 0; j < theRow.length; j++) {
if (theRow[j] != '\0') {
text.append(theRow[j]);
}
}
}
String s = text.toString();
System.out.println("s.length()="+s.length()+" s="+s);
Prints:
s.length()=6 s=ABDEFG
Note that '' is not a valid character, and '\0' is fine to use.

Nested for loop, not picking up first instance in Array

I am trying to encode a word, and I am not sure why my for loops aren't picking up the first instance, 0. The input for this method is "This" and 3. The output from this method is klv. So my loop must not be working properly as the letter T is getting skipped. What is wrong with my loops?
String encodeWord(String word, int Shift) {
//word = "This"
//Shift = 3, is how far the letter is shifted to the right of the original
char[] alphabet = "abcdefghijklmnopqrstuvwxyz".toCharArray();
char[] temp = word.toCharArray();
char[] FA = new char[temp.length];
String tempWord = "";
StringBuilder sb = new StringBuilder(64);
for (int x = 0; x < word.length(); x++) {
for (int y = 0; y < alphabet.length; y++) {
if (word.charAt(0) == alphabet[y]) {
FA[0] = alphabet[y + shift];
System.out.println(FA[0]);
}
}
}
for (int i = 0; i < word.length(); i++) {
for (int j = 0; j < alphabet.length; j++) {
if (word.charAt(i) == alphabet[j]) {
FA[i] = alphabet[j + shift];
sb.append(FA[i]);
System.out.println(FA[i]);
}
}
}
System.out.println(sb);
return sb.toString();
}
The letter 'T' is different from the letter 't', so since only the letter 't' is found in your array, the program won't find a match for the letter 'T'.
Another problem with your code is that you will get an Index out of bounds exception if the input contains the letters 'x', 'y' or 'z' because there aren't 3 letters after them in the array.
public static String encoder(String word, int shift)
{
static const int max_char = 122; //letter 'z'
static const int min_char = 97; //letter 'a'
char[] c_array = word.toCharArray();
char[] encoded_string = new char[c_arary.length()];
for(for i = 0; i < c_array.length(); i++)
{
if( ((int)c + shift) > max_char) //makes sure that the ascii isnt a non number
{
encoded_string[i] = (min_char + (int)c + shift - max_char ); // this will correct the overflow
}
c = c + shfit;
}
return encoded_string;
}
This is an easier way to do this... also your loops have a few logical errors.. the first one i caught was in the first loop... if there is a z in your word your going to overflow your alphabet array.
This is using the Ascii table way

in repeated string finding the total number of time the occurrence of any character

Given an integer,n, find and print the number of letter a's in the first n letters of infinite string.
For example, if the string s='abcac' and n=10, the substring we consider is abcacabcac , the first 10 characters of her infinite string. There are 4 occurrences of a in the substring.
static long repeatedString(String s, long n) {
long len = s.length(), count = 0;
StringBuilder sb = new StringBuilder("");
char[] c = s.toCharArray();
for (int i = 0; i < n; i++) {
sb.append(c[(i % len)]);
if (sb.charAt(i) == 'a')
count++;
}
return count;
}
it is showing error
incompatible types: possible lossy conversion from long to int
sb.append(c[i%len]);
if i am type casting the len then it is not passing the test case for the value whose length is greater than 10^9 for example if my input is
a
1000000000000
then the output must be 1000000000000
note-> for any given input i have to calculate the total number of 'a'
present in that given string
EDIT:i am calling my function as
long result = repeatedString("a", 1000000000000);
Part of your question seemed a bit vague, but from the last line, I get that, you want to find number of occurrences of a particular character in a string.
You can use a HashMap to add the unique characters of your String and set the value as the number of occurrences of the character.
What I am saying, looks something like this in code:
HashMap<Character,Integer> hm = new HashMap<Character,Integer>();
char[] str = s.toCharArray();
for(char c : str) {
if(hm.containsKey(c))
hm.put(c, hm.get(c)+1);
else
hm.put(c, 1);
}
Now you can just choose the character of your choice in the string to get it's number of occurrences, like this:
if(hm.get(character)!=null)
ans = hm.get(character);
else
ans = 0;
There is also a library, I am making for this here.
Edit:
From the edit, the question is much more clear, for that all you need to do is to add the characters of your string to the previous string, until the length is met.
After that, you can use the new string like in the code, I've given here.
You don't need a StringBuilder.
Get the result you want by iterating the initial string and multiply it as many times as needed, meaning by (n / len), then add what is left by the division:
static long repeatedString(String s, long n) {
long len = s.length();
if (len == 0)
return 0;
long rep = n / len;
long count = 0;
for (int i = 0; i < len; i++) {
if (s.charAt(i) == 'a')
count++;
}
count *= rep;
long rest = n % len;
for (int i = 0; i < rest; i++) {
if (s.charAt(i) == 'a')
count++;
}
return count;
}
I think you do not have to use StringBuidler (moreover, for big n, this could flow OutOfMemoryError), but count required letters on the fly.
public static long repeatedString(String str, long n, char ch) {
long count = 0;
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == ch)
continue;
count += n / str.length();
count += i < n % str.length() ? 1 : 0;
}
return count;
}

Need to find the character most frequent in a string and return the number of times it appears

public static int mostCommonChar(String foog){
int anArray[] = new int[foog.length()];
int foober = 0;
char f;
for (int i = 0; i > foog.length(); i++){
f = foog.charAt(i);
foober = 1;
for (int j = i + 1; j < foog.length(); j++){
if (f == foog.charAt(j)){
foober++;
}
anArray[i] = foober;
}
}
Arrays.sort(anArray);
int max = anArray[anArray.length - 1];
System.out.println(max);
return 5;
}
The return 5 is just so it works, then when it does I'll return max but for now I have to print it.
Now I'm pretty sure I messed up a lot of things. But I think that they highest number would still go to the end and by sorting the array I can retrieve the number of times the most frequent character appeared.
For the string, I used "habakkuk" and I expected "3" to print given there are 3 k's but it didn't. Could anyone tell me what I am doing wrong? Thanks!
You just have a small typo
for (int j = i + 1; j > foog.length(); j++)
should be
for (int j = i + 1; j < foog.length(); j++)
Sidenote: You can improve your algorithm. Right now it runs in O(n²) but you can do it in O(nlogn) by keeping a counter for each letter in the alphabet.
int[] charCount = new int[26];
char[] chars = foog.toLowerCase().toCharArray();
for (char c : chars) {
charCount[c - 'a']++;
}
Arrays.sort(charCount);
int max = charCount[charCount.length - 1];
Or you can make it even run in O(n) by just looking at the maximum value, you do not even have to sort.
int[] charCount = new int[26];
char[] chars = foog.toLowerCase().toCharArray();
for (char c : chars) {
charCount[c - 'a']++;
}
int max = Arrays.stream(charCount).max().getAsInt();
Just a suggestion ;-)

Categories