How to sort integer array without losing location - java

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;
}
}

Related

how to solve the indexing in java programming language

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());
}

Java program to find the letter that appears in the most words?

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

Write a program to print each and every alphabet with how many occured in a user input

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 !

Word count java

So my code is supposed to return the amount of words (words being lengths of letters) and it works except for when i enter anything 0 or less can some pplease help spot the error??
Edited Code:
public class WordCount {
public static int countWords(String original, int minLength){
String[] s1 = original.split("\\s+");
for(int i = 0; i < s1.length; i++){
s1[i] = s1[i].replaceAll("^\\W]", "");
}
int count = 0;
for(int i = 0; i < s1.length; i++){
String str = s1[i];
int len = 0;
for(int x = 0; x < str.length(); x++){
char c = str.charAt(x);
if(Character.isLetter(c) == true){
len ++;
}
}
if(len >= minLength){
count ++;
}
}
return count;
}
public static void main(String[] args){
System.out.println("enter string: ");
String s = IO.readString();
System.out.println("min length: ");
int m = IO.readInt();
System.out.println(countWords(s, m));
}
}
I would apply a solution that uses a regular expression to process the text.
I prepared a sketch of code, which can be summarized as follows:
String[] words = myString.replaceAll("[^a-zA-Z ]", " ").split("\\s+");
What this code does is to:
replace whatever is not a letter (since you said just letters) with a space
split the results on the spaces
The resulting array words contains all the words (i.e., sequences of letters) which were contained in the original string.
A full example can be found here. In this example I just print the words as a list. In case you want just the count of words, you just have to return the count of elements in the array.
Try this :
String s = original.replaceAll("[\\W]", " ").replaceAll("[\\s]+", " ");
because you have to replace spaces more than 1 here as well.

How to split a string into equal parts and store it in a string array

I'm fairly new to Java and am stuck on a particular homework question where a String gets passes and from there I have to split it into parts equal to an Integer that was passed.
For example: String "HelloWorld" is input and it has to be divided by 2 and those parts then have to be put into an array that has two parts like: array[hello, world].
Is there anyway to do this using a FOR loop?
My code so far enters the whole String into each array element. Here is my code:
String[] splitIntoParts(String word, int size) {
String[] array = new String[size];
for (int i = 0; i < array.length; i++) {
array[i] = word;
println(array[i]);;
}
return array;
}
There are many ways:
Here's the regex version:
public void splitEqual(String s){
int length = s.length();//Get string length
int whereToSplit;//store where will split
if(length%2==0) whereToSplit = length/2;//if length number is pair then it'll split equal
else whereToSplit = (length+1)/2;//else the first value will have one char more than the other
System.out.println(Arrays.toString(s.split("(?<=\\G.{"+whereToSplit+"})")));//split the string
}
\G is a zero-width assertion that matches the position where the previous match ended. If there was no previous match, it matches the beginning of the input, the same as \A. The enclosing lookbehind matches the position that's four characters along from the end of the last match.
Both lookbehind and \G are advanced regex features, not supported by all flavors. Furthermore, \G is not implemented consistently across the flavors that do support it. This trick will work (for example) in Java, Perl, .NET and JGSoft, but not in PHP (PCRE), Ruby 1.9+ or TextMate (both Oniguruma).
Using Substring:
/**
* Split String using substring, you'll have to tell where to split
* #param src String to split
* #param len where to split
* #return
*/
public static String[] split(String src, int len) {
String[] result = new String[(int)Math.ceil((double)src.length()/(double)len)];
for (int i=0; i<result.length; i++)
result[i] = src.substring(i*len, Math.min(src.length(), (i+1)*len));
return result;
}
You should also check this answer: Google Guava split
First check if the length of the string is a multiple of the divisor:
if(str.length() % divisor == 0)
Then you know that you can grab equal chunks of it. So you use substring to pull them out, in a loop.
while(str.length() > 0) {
String nextChunk = str.substring(0,divisor);
// store the chunk.
str = str.substring(divisor,str.length());
}
Will cycle through and grab a chunk that is divisor long each time.
Try the following application.It is dividing the provided word into equal parts based on the provided size per part
public class WordSpliter {
public static void main(String[] args) {
String[] words = new WordSpliter().splitter("abcdefghij", 4);
for(String s : words) System.out.println(s);
}
private String[] splitter(String word, int size) {
// Decide the size of the String array
int rest = word.length() % size;
int arrSize = ((word.length() - rest) / size) + 1;
// Declare the array and the start point of the word
String[] words = new String[arrSize];
int startPoint = 0;
for (int i = 0; i < words.length; i++) {
if (i + 1 == words.length) {
words[i] = word.substring(startPoint, startPoint + rest);
} else {
words[i] = word.substring(startPoint, startPoint + 4);
startPoint += 4;
}
}
return words;
}
}
Good Luck !!!!
You can use Brute force
public static List<String> splitStringEqually(String text, int size)
{
List<String> result = new ArrayList<String>((text.length() + size - 1) / size);
for (int i = 0; i < text.length(); i += size) {
result.add(text.substring(i, Math.min(text.length(), i + size)));
}
return result;
}
String s = "HelloWorld";
String firts_part=(String) s.subSequence(0, s.length() / 2);
String second_part=(String) s.subSequence((s.length() / 2)+1,s.length()-1 );
Try subSequence();
This is not plagarism, formatted the answer mentioned here - https://stackoverflow.com/a/3761521 as per the question.
public static void main(String[] args){
String str = "HelloWorld";
int parts = str.length()/3;
System.out.println(Arrays.toString(
str.split("(?<=\\G.{"+parts+"})")
));
}
Since length of a string is dived by 2
Code:
String st ="HelloWorld";
String firstPart = "";
String secondPart = "";
for (int j = 0; j < st.length(); j++) {
if ( j < st.length() /2) {
firstPart += st.charAt(j);
}else
secondPart += st.charAt(j);
}
System.out.println(firstPart);
System.out.println(secondPart);
Output:
Hello
World
Explanation: you add to firstPart String as long as your index has not met the middle index of the String. When it passed the middle index of String, you make the secondPart
Just looking at your input HelloWorld, You are trying to substring your input by Upper case letter.
You should go with that.
String str = "HelloWorldUser";
List<Integer> indexList = new ArrayList<>();
for (int i = 0; i < str.length(); i++) {
String temp = (str.charAt(i) + "").toUpperCase();
if (temp.equals(str.charAt(i) + "")) { // check for upper case letters
indexList.add(i);
}
}
List<String> subStrings = new LinkedList<>(); // to keep the insertion order
for (int i = indexList.size() - 1; i > -1; i--) { // substring reverse order
subStrings.add(str.substring(indexList.get(i)));
str=str.substring(0,indexList.get(i));
}
Collections.reverse(subStrings); // reverse to get original order
System.out.println(subStrings);
Out put:
[Hello, World, User]
If you want to get final result in to an array you can use
String[] arr= subStrings.toArray(new String[subStrings.size()]);
I figured it out. Here is my code:
String[] array = new String[size];
char[] charArray = new char[length(word)];
char[] temp = new char[length(word) / size];
int place = 0;
// turn the string into an array of chars
for (int i = 0; i < charArray.length; i++) {
charArray[i] = getChar(word, i);
}
// loop for each element of the desired string array
for (int i = 0; i < array.length; i++) {
// fill a temp array with the correct characters and the corect amount of characters
for (int j = 0; j < charArray.length / size; j++) {
temp[j] = charArray[place];
++place;
}
// insert the temp array into each element of the string array
array[i] = new String(temp);
}
return array;
A Simple solution is like
static void split(String str, int n) {
int partSize = str.length() / n;
while (str.length() - partSize > 0) {
String s = str.substring(0, partSize-1);
System.out.print(s + " ");
str = str.substring(partSize-1);
}
if (str.length() > 0) {
System.out.print(str);
}
}
You can do it using regex as follows:
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
// Tests
System.out.println(Arrays.toString(splitIntoParts("HelloWorld", 5)));
System.out.println(Arrays.toString(splitIntoParts("HelloWorld", 4)));
System.out.println(Arrays.toString(splitIntoParts("HelloWorld", 2)));
}
static String[] splitIntoParts(String word, int size) {
return word.replaceAll("(.{" + size + "})", "$1\n").split("\n");
}
}
Output:
[Hello, World]
[Hell, oWor, ld]
[He, ll, oW, or, ld]

Categories