public static int indexOf(String text , char index){
char array [] = new char[text.length()];
for(int i = 0 ; i < text.length(); i++){
array[i] = text.charAt(i);
}// end of first loop
// the above loop converts the string obj to char array
for(int i = 0 ; i < array.length; i++){
if(array[i] == index){ // if a given letter is exist in string
System.out.println("The index of " + index + " is " + i);
return i; // show or return the index of that given letter
}
}//end of second loop
System.out.println("The Letter you Entered does not Exist");
return -1;
}// end of method
this piece of code is for finding the index of string ;
first it takes a string and a character as an input than it convert it to array of characters than it search for an given lettter if it finds it.
method will return it's index but the main problem is that we have more than one same letter in a string so it will return the first one .
and how could i detect the second one or how I can differentiate the second same letter and show it is index for example:
indexOf("kingJoker",'k');
here in kingjoker string we have two k letter the method can't find second k index so that is the problem.
Change the return type of your method to int[]
Walk the string once to count the matches
Make an array of the size equal to the count
Walk the string again, populating the return indexes as you go.
Here is your modified implementation:
public static int[] indexesOf(String text , char ch) {
int count = 0;
for (int i = 0 ; i != text.length() ; i++) {
if (text.charAt(i) == ch) {
count++;
}
}
int[] indexes = new int[count];
int pos = 0;
for (int i = 0 ; i != text.length() ; i++) {
if (text.charAt(i) == ch) {
System.out.println("Found '" + ch + "' at " + i);
indexes[pos++] = i;
}
}
return indexes;
}
To detect multiple letters, I recommend you store every index within a List<Integer>. You can use the following (courtesy of smac89's answer):
public static List<Integer> indexOf(String text, char index) {
return IntStream.range(0, text.length())
.filter(i -> s.charAt(i) == index)
.boxed()
.collect(Collectors.toList());
}
Related
I have a function called lengthOfLongestSubstring and its job is to find the longest substring without any repeated characters. For the most part, it works, but when it gets an input like "dvdf" it prints out 2 (rather than 3) and gives [dv, df] when it should be [d, vdf].
So, I first go through the string and see if there are any unique characters. If there are, I append it to the ans variable. (I think this is the part that needs some fixing). If there is a duplicate, I store it in the substrings linked list and reset the ans variable to the duplicate string.
Once the whole string has been traversed, I find the longest substring and return its length.
public static int lengthOfLongestSubstring(String s) {
String ans = "";
int len = 0;
LinkedList<String> substrings = new LinkedList<String>();
for (int i = 0; i < s.length(); i++) {
if (!ans.contains("" + s.charAt(i))) {
ans += s.charAt(i);
} else {
substrings.add(ans);
ans = "" + s.charAt(i);
}
}
substrings.add(ans); // add last seen substring into the linked list
for (int i = 0; i < substrings.size(); i++) {
if (substrings.get(i).length() >= len)
len = substrings.get(i).length();
}
System.out.println(Arrays.toString(substrings.toArray()));
return len;
}
Here are some test results:
//correct
lengthOfLongestSubstring("abcabcbb") -> 3 ( [abc, abc, b, b])
lengthOfLongestSubstring("pwwkew") -> 3 ([pw, wke, w]).
lengthOfLongestSubstring("ABDEFGABEF"); -> 6 ([ABDEFG, ABEF])
// wrong
System.out.println(lengthOfLongestSubstring("acadf")); -> 3, ([ac, adf]) *should be 4, with the linked list being [a, cadf]
Any suggestions to fix this? Do I have to redo all my logic?
Thanks!
You code is mistakenly assuming that when you find a repeated character, the next candidate substring starts at the repeated character. That is not true, it starts right after the original character.
Example: If string is "abcXdefXghiXjkl", there are 3 candidate substrings: "abcXdef", "defXghi", and "ghiXjkl".
As you can see, the candidate substrings ends before a repeating character and starts after a repeating character (and begin and end of string).
So, when you find a repeating character, the position of the previous instance of that character is needed to determine the start of the next substring candidate.
The easiest way to handle that, is to build a Map of character to last seen position. That will also perform faster than continually performing substring searches to check for repeating character, like the question code and the other answers are doing.
Something like this:
public static int lengthOfLongestSubstring(String s) {
Map<Character, Integer> charPos = new HashMap<>();
List<String> candidates = new ArrayList<>();
int start = 0, maxLen = 0;
for (int idx = 0; idx < s.length(); idx++) {
char ch = s.charAt(idx);
Integer preIdx = charPos.get(ch);
if (preIdx != null && preIdx >= start) { // found repeat
if (idx - start > maxLen) {
candidates.clear();
maxLen = idx - start;
}
if (idx - start == maxLen)
candidates.add(s.substring(start, idx));
start = preIdx + 1;
}
charPos.put(ch, idx);
}
if (s.length() - start > maxLen)
maxLen = s.length() - start;
if (s.length() - start == maxLen)
candidates.add(s.substring(start));
System.out.print(candidates + ": ");
return maxLen;
}
The candidates is only there for debugging purposes, and is not needed, so without that, the code is somewhat simpler:
public static int lengthOfLongestSubstring(String s) {
Map<Character, Integer> charPos = new HashMap<>();
int start = 0, maxLen = 0;
for (int idx = 0; idx < s.length(); idx++) {
char ch = s.charAt(idx);
Integer preIdx = charPos.get(ch);
if (preIdx != null && preIdx >= start) { // found repeat
if (idx - start > maxLen)
maxLen = idx - start;
start = preIdx + 1;
}
charPos.put(ch, idx);
}
return Math.max(maxLen, s.length() - start);
}
Test
System.out.println(lengthOfLongestSubstring(""));
System.out.println(lengthOfLongestSubstring("x"));
System.out.println(lengthOfLongestSubstring("xx"));
System.out.println(lengthOfLongestSubstring("xxx"));
System.out.println(lengthOfLongestSubstring("abcXdefXghiXjkl"));
System.out.println(lengthOfLongestSubstring("abcabcbb"));
System.out.println(lengthOfLongestSubstring("pwwkew"));
System.out.println(lengthOfLongestSubstring("ABDEFGABEF"));
Output (with candidate lists)
[]: 0
[x]: 1
[x, x]: 1
[x, x, x]: 1
[abcXdef, defXghi, ghiXjkl]: 7
[abc, bca, cab, abc]: 3
[wke, kew]: 3
[ABDEFG, BDEFGA, DEFGAB]: 6
Instead of setting ans to the current char when a character match is found
ans = "" + s.charAt(i);
You should add the current char to all the characters after the first match of the current char
ans = ans.substring(ans.indexOf(s.charAt(i)) + 1) + s.charAt(i);
The full method thus becomes
public static int lengthOfLongestSubstring(String s) {
String ans = "";
int len = 0;
LinkedList<String> substrings = new LinkedList<>();
for (int i = 0; i < s.length(); i++) {
if (!ans.contains("" + s.charAt(i))) {
ans += s.charAt(i);
} else {
substrings.add(ans);
// Only the below line changed
ans = ans.substring(ans.indexOf(s.charAt(i)) + 1) + s.charAt(i);
}
}
substrings.add(ans); // add last seen substring into the linked list
for (int i = 0; i < substrings.size(); i++) {
if (substrings.get(i).length() >= len)
len = substrings.get(i).length();
}
System.out.println(Arrays.toString(substrings.toArray()));
return len;
}
Using this code the acceptance criteria you specified passed successfully
//correct
lengthOfLongestSubstring("dvdf") -> 3 ( [dv, vdf])
lengthOfLongestSubstring("abcabcbb") -> 3 ([abc, bca, cab, abc, cb, b])
lengthOfLongestSubstring("pwwkew") -> 3 ([pw, wke, kew]).
lengthOfLongestSubstring("ABDEFGABEF"); -> 6 ([ABDEFG, BDEFGA, DEFGAB, FGABE, GABEF])
lengthOfLongestSubstring("acadf"); -> 4 ([ac, cadf])
Create a nested for loop to check at each index in the array.
public static int lengthOfLongestSubstring(String s) {
String ans = "";
int len = 0;
LinkedList<String> substrings = new LinkedList<String>();
int k = 0;
for (int i = 0; i < s.length(); i++) {
if(k == s.length()) {
break;
}
for(k = i; k < s.length(); k++) {
if (!ans.contains("" + s.charAt(k))) {
ans += s.charAt(k);
} else {
substrings.add(ans);
ans = "";
break;
}
}
}
substrings.add(ans); // add last seen substring into the linked list
for (int i = 0; i < substrings.size(); i++) {
if (substrings.get(i).length() >= len)
len = substrings.get(i).length();
}
System.out.println(Arrays.toString(substrings.toArray()));
return len;
}
Example:
lengthOfLongestSubstring("ABDEFGABEF"); -> 6 ([ABDEFG, BDEFGA, DEFGAB, EFGAB, FGABE, GABEF])
I have a sentence, and I want to find the char that appears in the most words, and how many words it appears in.
For example: "I like visiting my friend Will, who lives in Orlando, Florida."
Which should output I 8.
This is my code:
char maxChar2 = '\0';
int maxCount2 = 1;
for (int j=0; j<strs2.length; j++) {
int charCount = 1;
char localChar = '\0';
for (int k=0; k<strs2[j].length(); k++) {
if (strs2[j].charAt(k) != ' ' && strs2[j].charAt(k) != maxChar2) {
for (int l=k+1; l<strs2[j].length(); l++) {
if (strs2[j].charAt(k)==strs2[j].charAt(l)) {
localChar = strs2[j].charAt(k);
charCount++;
}
}
}
}
if (charCount > maxCount2) {
maxCount2 = charCount;
maxChar2 = localChar;
}
}
, where strs2 is a String array.
My program is giving me O 79. Also, uppercase and lowercase do not matter and avoid all punctuation.
As a tip, try using more meaningful variable names and proper indentation. This will help a lot especially when your program is not doing what you thought it should do. Also starting smaller and writing some tests for it will help a bunch. Instead of a full sentence, get it working for 2 words, then 3 words, then a more elaborate sentence.
Rewriting your code to be a bit more readable:
// Where sentence is: "I like".split(" ");
private static void getMostFrequentLetter(String[] sentence) {
char mostFrequentLetter = '\0';
int mostFrequentLetterCount = 1;
for (String word : sentence) {
int charCount = 1;
char localChar = '\0';
for (int wordIndex = 0; wordIndex < word.length(); wordIndex++) {
char currentLetter = word.charAt(wordIndex);
if (currentLetter != ' ' && currentLetter != mostFrequentLetter) {
for (int l = wordIndex + 1; l < word.length(); l++) {
char nextLetter = word.charAt(l);
if (currentLetter == nextLetter) {
localChar = currentLetter;
charCount++;
}
}
}
}
if (charCount > mostFrequentLetterCount) {
mostFrequentLetterCount = charCount;
mostFrequentLetter = localChar;
}
}
}
Now all I did was rename your variables and change your for loop to a for-each loop. By doing this you can see more clearly your algorithm and what you're trying to do. Basically you're going through each word and comparing the current letter with the next letter to check for duplicates. If I run this with "I like" i should get i 2 but instead I get null char 1. You aren't properly comparing and saving common letters. This isn't giving you the answer, but I hope this makes it more clear what your code is doing so you can fix it.
Here is a somewhat more elegant solution
public static void FindMostPopularCharacter(String input)
{
String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
input = input.toUpperCase();
HashMap<Character, Integer> charData = new HashMap<>();
char occursTheMost = 'A'; //start with default most popular char
int maxCount = 0;
//create the map to store counts of all the chars seen
for(int i = 0; i < alphabet.length(); i++)
charData.put(alphabet.charAt(i), 0);
//first find the character to look for
for(int i = 0; i < input.length(); i++)
{
char c = input.charAt(i);
//if contained in our map increment its count
if(charData.containsKey(c))
charData.put(c, charData.get(c) + 1);
//check for a max count and set the values accordingly
if(charData.containsKey(c) && charData.get(c) > maxCount)
{
occursTheMost = c;
maxCount = charData.get(c);
}
}
//final step
//now split it up into words and search which contain our most popular character
String[] words = input.split(" ");
int wordCount = 0;
CharSequence charSequence;
for(Character character : charData.keySet())
{
int tempCount = 0;
charSequence = "" + character;
for(int i = 0; i < words.length; i++)
{
if(words[i].contains(charSequence))
tempCount++;
}
if(tempCount > wordCount)
{
occursTheMost = character;
wordCount = tempCount;
}
}
System.out.println(occursTheMost + " " + wordCount);
}
Output of
String input = "I like visiting my friend Will, who lives in Orlando, Florida.";
FindMostPopularCharacter(input);
is
I 8
Note: If there are ties this will only output the character that first reaches the maximum number of occurrences.
FindMostPopularCharacter("aabb aabb aabb bbaa");
Outputs
B 4
because B reaches the max first before A due to the last word in the input.
FindMostPopularCharacter("aab aab b")
B 3
I am writing my own Radix Sort method to sort the words in a String (the big black cat sat on the
beautiful brown mat would be sorted as beautiful big black brown cat mat on sat the the). The method takes in a List (my own List interface) of the individual words and reorders the list in place.
Here is my method so far:
public static void stringRadixSort(List<String> list, int letters) {
List<String>[] buckets = (List<String>[]) Array.newInstance(List.class, 26);
int letterNumber = 1; //Sorts list by 1st letter of each word, then 2nd etc.
for (int i = 0; i < letters; i++) {
while (!list.isEmpty()) {
String word = list.remove(list.first());
if (word.length() > letters) throw new UnsortableException("The list contains a word that holds more letters than the given maximum number of letters."
+ "\nMax Letters: " + letters + "\nWord: " + word);
String letter = word.substring(letterNumber - 1, letterNumber); //EXCEPTION THROWN
char ch = letter.charAt(0);
int index = ch - 'a'; //gets index of each letter ('a' = buckets[0], 'z' = buckets[25]
if (buckets[index] == null) {
buckets[index] = new LinkedList<String>();
}
buckets[index].insertLast(word);
}
for (int j = 0; j < buckets.length; j++) {
if (buckets[j] != null) {
while (!buckets[j].isEmpty()) {
list.insertLast(buckets[j].remove(buckets[j].first()));
}
}
}
letterNumber++;
}
}
The (only, I hope) problem with my method is that when I am reading each character of the word, I create a single letter substring of the word. As the outer for loop runs through letters times (where letters is the maximum length of a word in the List), the exception is thrown when this loop is on an iteration greater than the length of the current word - i.e. letterNumber > word.length() - and so it is attempting to create a substring using String Indexes which are greater than the String's length.
How can I adjust my method so that it only creates substrings of each word until letterNumber == word.length(), and also then be able to apply the sorting algorithm to these shorter words - "a" would become before "aa".
Just group the elements that are shorter than the string length in a additional group. Also you need to sort the least significant (relevant) character first. The following code uses java collections instead of whatever datastructure you were using:
public static void stringRadixSort(List<String> list, int letters) {
if (list.size() <= 1) {
return;
}
List<String>[] buckets = new List[27];
for (int i = 0; i < buckets.length; i++) {
buckets[i] = new LinkedList<>();
}
int largestLength = -1;
int secondLargestLength = 0;
for (String s : list) {
int length = s.length();
if (length >= largestLength) {
secondLargestLength = largestLength;
largestLength = length;
} else if (secondLargestLength < length) {
secondLargestLength = length;
}
}
if (largestLength > letters) {
throw new IllegalArgumentException("one of the strings is too long");
}
for (int i = secondLargestLength == largestLength ? secondLargestLength-1 : secondLargestLength; i >= 0; i--) {
for (String word : list) {
int index = (word.length() <= i) ? 0 : word.charAt(i) - ('a' - 1);
buckets[index].add(word);
}
list.clear();
for (List<String> lst : buckets) {
if (lst != null) {
list.addAll(lst);
lst.clear();
}
}
}
}
Why don't you replace
String letter = word.substring(letterNumber - 1, letterNumber);
char ch = letter.charAt(0);
with
char ch = word.charAt(letterNumber - 1);
which gives you the char directly. But this doesn't solve the problem with the IndexOutOfBoundException.
You should of course catch the exception and handle it. Maybe it is good to create a bucket for this case: When the word is too short for the current iteration, it is sorted into a bucket. When merging the list back together, take the elements of this bucket first.
public static void stringRadixSort(List<String> list, int letters) {
List<String>[] buckets = (List<String>[]) Array.newInstance(List.class, 27);
int letterNumber = 1; //Sorts list by 1st letter of each word, then 2nd etc.
for (int i = 0; i < letters; i++) {
while (!list.isEmpty()) {
String word = list.remove(list.first());
if (word.length() > letters) throw new UnsortableException("The list contains a word that holds more letters than the given maximum number of letters."
+ "\nMax Letters: " + letters + "\nWord: " + word);
int index;
if(word.length() > letterNumber) {
char ch = word.charAt(letterNumber - 1);
index = ch - 'a' + 1; //gets index of each letter ('a' = buckets[1], 'z' = buckets[26], buckets[0] is for short words
} else {
index = 0;
}
if (buckets[index] == null) {
buckets[index] = new LinkedList<String>();
}
buckets[index].insertLast(word);
}
for (int j = 0; j < buckets.length; j++) {
if (buckets[j] != null) {
while (!buckets[j].isEmpty()) {
list.insertLast(buckets[j].remove(buckets[j].first()));
}
}
}
letterNumber++;
}
}
Throughout all my attempts, I had been sorting the words by most significant letter first (1st letter of each word), then the next significant, and so on. Of course, Radix sort relies on sorting the least significant digit/letter (the last digit/letter of the number/word). So, instead of iterating through my outer for loop starting by focusing on letterNumber = 1 and incrementing this after each iteration, I instead began with letterNumber = maxWordLength, and then decremented this after each iteration, so that each iteration compares the next most significant letter.
#SuppressWarnings("unchecked")
public static void stringRadixSort(List<String> list) {
List<String>[] buckets = (List<String>[]) Array.newInstance(List.class, 27);
//Find longest word in list
int maxWordLength = 0;
for (String word : list) {
if (word.length() > maxWordLength) {
maxWordLength = word.length();
}
}
//Sorts list based on least significant letter (last letter of word) to most significant
int letterNumber = maxWordLength;
for (int i = 0; i < maxWordLength; i++) {
while (!list.isEmpty()) {
String word = list.remove(list.first());
int index = 0;
if(word.length() >= letterNumber) {
char ch = word.charAt(letterNumber - 1);
index = ch - 'a' + 1; //gets index of each letter ('a' = buckets[1], 'z' = buckets[26], buckets[0] is for words shorter than 'letterNumber')
}
if (buckets[index] == null) {
buckets[index] = new LinkedList<String>();
}
buckets[index].insertLast(word);
}
for (int j = 0; j < buckets.length; j++) {
if (buckets[j] != null) {
while (!buckets[j].isEmpty()) {
list.insertLast(buckets[j].remove(buckets[j].first()));
}
}
}
letterNumber--;
}
}
I'm making a program which receives a string as input and returns the "sum" of the values for each letter of each word.
For example, my input of "Take advantage, do your best, don't stress.", would return:
do(19) take(37) dont(43) best(46) advantage(75) your(79) stress(100)
"do" would have a value of 19 because the letter "d" has a value of 4 (it is the fourth letter of the alphabet), and "o" has a value of 15, so the total is 19.
Now to store these values I have two arrays, one string array for each word, and one int array for the point value that they have. However, I only have this so far:
take(37) advantage(75) do(19) your(79) best(46) dont(53) stress(100)
As you can see, it is not sorted in ascending order as I am trying to do. I display these values like this:
System.out.print(words[j] + "(" + points[j] + ")" + " ");
where words is the String array and points is the int array. How can I sort them?
My current code:
public static void main (String[] args)
{
String input = "Take advantage, do your best, don't stress.";
String output = "";
//Get rid of all punctuation
for(int i = 0; i < input.length(); i++){
if( ( (int)input.charAt(i) >= 65 && (int)input.charAt(i) <= 90) || (int)input.charAt(i) == 32 || ( (int)input.charAt(i) >= 97 && (int)input.charAt(i) <= 122)){
//Handles Uppercase
if(input.charAt(i) >= 65 && input.charAt(i) <= 90){
int temp = (int)input.charAt(i) + 32;
char c = (char)temp;
output += c;
}
//Handles all other characters
else{
output += input.charAt(i);
}
}
}
//Done punctuation
String[] words = output.split(" ");
int[] points = new int[words.length];
//Points assignment
for(int j = 0; j < words.length; j++){
for(int k = 0; k < words[j].length(); k++){
points[j] += (int)words[j].charAt(k) - 96;
}
System.out.print(words[j] + "(" + points[j] + ")" + " ");
}
}
How about storing your results in a Map<String,Integer> instead of two lists:
Map myMap = new HashMap<String,Integer>;
From there you can sort the Map by its values: Sort a Map<Key, Value> by values (Java)
Next you can iterate through the sorted map:
for(String s : myMap.keySet()){
System.out.println(s+"("+myMap.get(s)+")");
}
If that is an option, your code can be made much simpler with Java 8.
First of all, removing punctuation can be done with a simple regular expression: you only want to keep letters, so we can just remove everything that is neither a letter nor a space. This is done by calling replaceAll("[^a-zA-Z\\s]", ""). After that, we can get a hold of all the words by splitting around "\\s+" (i.e. all whitespace characters).
Then, let's create a helper method returning the value of a String. As you have in your question, this would just be:
private static int value(String str) {
return str.chars().map(c -> c - 'a' + 1).sum();
}
Finally, we need to sort the words array with a comparator comparing the value of each word. The comparator is created with the help of Comparator.comparingInt(keyExtractor) where the key extraction would be a function returning the value of a word. In this case, it could be expressed a lambda expression: word -> value(word).
To have the final output, we need to transform the words array into a String where each word is concatenated with its value in parentheses. This is done by creating a Stream<String> of the words (Arrays.stream(array)), sorting it according the comparator above (sorted(comparator)), mapping each word to the result of concatenating its value to it and finally collecting that into a String delimited by a space (Collectors.joining(delimiter)).
Whole code would be:
public static void main(String[] args) {
String str = "Take advantage, do your best, don't stress.";
String[] words = str.toLowerCase().replaceAll("[^a-zA-Z\\s]", "").split("\\s+");
String output =
Arrays.stream(words)
.sorted(Comparator.comparingInt(w -> value(w)))
.map(w -> w + "(" + value(w) + ")")
.collect(Collectors.joining(" "));
System.out.println(output);
}
private static int value(String str) {
return str.chars().map(c -> c - 'a' + 1).sum();
}
Use any of sorting algorithm and do sorting for both arrays. For example:
public static void bubbleSort(int[] numArray, String[] words) {
int n = numArray.length;
int temp = 0;
String tt;
for (int i = 0; i < n; i++) {
for (int j = 1; j < (n - i); j++) {
if (numArray[j - 1] > numArray[j]) {
temp = numArray[j - 1];
tt=words[j-1];
numArray[j - 1] = numArray[j];
words[j-1]=words[j];
numArray[j] = temp;
words[j]=tt;
}
Then change last part of your main function to look like this:
String[] words = output.split(" ");
int[] points = new int[words.length];
//Points assignment
for(int j = 0; j < words.length; j++){
for(int k = 0; k < words[j].length(); k++){
points[j] += (int)words[j].charAt(k) - 96;
}
}
bubbleSort(points,words);
for(int j = 0; j < words.length; j++){
System.out.print(words[j] + "(" + points[j] + ")" + " ");
}
If you are not allowed to use Java 8 (else use #Tunaki's approach), create a Comparable object that keeps two values, a String (word) and an int (sum). Then, just add each word to a list and sort it using Collections.sort(yourList).
public class Word implements Comparable<Word>{
private String word;
private int sum;
public Word(String word) {
this.word = word;
setSum();
}
private void setSum() {
//your sum function, I just copy and paste it from your post
for(int k = 0; k < word.length(); k++)
sum += (int)word.charAt(k) - 96;
}
public String getWord() {
return word;
}
public int getSum() {
return sum;
}
#Override
public int compareTo(Word o) {
return this.sum > o.sum ? 1 : -1;
}
}
I have to write a program to accept a String as input, and as output I'll have to print each and every alphabetical letter, and how many times each occurred in the user input. There are some constraints:
I cannot use built-in functions and collection
The printed result should be sorted by occurrence-value.
For example, with this input:
abbbccccdddddzz
I would expect this output:
a-1,z-2,b-3,c-4,d-5
This is what I have so far:
public static void isCountChar(String s) {
char c1[] = s.toCharArray();
int c3[] = new int[26];
for (int i = 0; i < c1.length; i++) {
char c = s.charAt(i);
c3[c - 'a']++;
}
for (int j = 0; j < c3.length; j++) {
if (c3[j] != 0) {
char c = (char) (j + 'a');
System.out.println("character is:" + c + " " + "count is: " + c3[j]);
}
}
}
But I don't know how to sort.
First of all a tip for your next question: The things you've stated in your comments would fit better as an edit to your question. Try to clearly state what the current result is, and what the expected result should be.
That being said, it was an interesting problem, because of the two constraints.
First of all you weren't allowed to use libraries or collections. If this wasn't a constraint I would have suggested a HashMap with character as keys, and int as values, and then the sorting would be easy.
Second constraint was to order by value. Most people here suggested a sorting like BubbleSort which I agree with, but it wouldn't work with your current code because it would sort by alphabetic character instead of output value.
With these two constraints it is probably best to fake key-value pairing yourself by making both an keys-array and values-array, and sort them both at the same time (with something like a BubbleSort-algorithm). Here is the code:
private static final int ALPHABET_SIZE = 26;
public static void isCountChar(String s)
{
// Convert input String to char-array (and uppercase to lowercase)
char[] array = s.toLowerCase().toCharArray();
// Fill the keys-array with the alphabet
char[] keys = new char[ALPHABET_SIZE];
for (int i = 0; i < ALPHABET_SIZE; i++)
{
keys[i] = (char)('a' + i);
}
// Count how much each char occurs in the input String
int[] values = new int[ALPHABET_SIZE];
for (char c : array)
{
values[c - 'a']++;
}
// Sort both the keys and values so the indexes stay the same
bubbleSort(keys, values);
// Print the output:
for (int j = 0; j < ALPHABET_SIZE; j++)
{
if (values[j] != 0)
{
System.out.println("character is: " + keys[j] + "; count is: " + values[j]);
}
}
}
private static void bubbleSort(char[] keys, int[] values)
{
// BUBBLESORT (copied from http://www.java-examples.com/java-bubble-sort-example and modified)
int n = values.length;
for(int i = 0; i < n; i++){
for(int j = 1; j < (n - i); j++){
if(values[j-1] > values[j]){
// Swap the elements:
int tempValue = values[j - 1];
values[j - 1] = values[j];
values[j] = tempValue;
char tempKey = keys[j - 1];
keys[j - 1] = keys[j];
keys[j] = tempKey;
}
}
}
}
Example usage:
public static void main (String[] args) throws java.lang.Exception
{
isCountChar("TestString");
}
Output:
character is: e; count is: 1
character is: g; count is: 1
character is: i; count is: 1
character is: n; count is: 1
character is: r; count is: 1
character is: s; count is: 2
character is: t; count is: 3
Here is a working ideone to see the input and output.
some sort: easy if not easiest to understand an coding
You loop from the first element to the end -1 : element K
compare element K and element K+1: if element K>element K+1, invert them
continue loop
if you made one change redo that !