I want to find how many words there are in a string but ignore the similar words in it.
For example the main method should return 8 insetad of 9.
I want it to be a method which takes one parameter s of type String and returns an int value. And im only allowed to use the bacics,so no HashMaps, ArrayLists, only charAt, length, or substring and using loops and if statemens are allowed.
public static void main(String[] args) {
countUniqueWords("A long long time ago, I can still remember");
public static int countUniqueWords(String str) {
char[] sentence = str.toCharArray();
boolean inWord = false;
int wordCt = 0;
for (char c : sentence) {
if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z') {
if (!inWord) {
wordCt++;
inWord = true;
}
} else {
inWord = false;
}
}
return wordCt;
}
```
Don't force yourself to limited options, and learn the Streaming API. Your question is as simple as:
public static long countUniqueWords(String str) {
var str2 = str.replaceAll("[^a-zA-Z0-9 ]", "").replaceAll(" +", " ");
return Arrays.stream(str2.split(" "))
.distinct()
.count();
}
[Optional step] Get get rid of all non alphanumeric chars
Split the string per empty slot
Remove duplicates
Add them together
To ignore same words in a string, you can use a combination of the split and distinct methods from the Java Stream API.
// Define the input string
String input = "This is a test string with some repeating words";
// Split the string into an array of words
String[] words = input.split("\\s+");
// Use the distinct method to remove duplicate words from the array
String[] distinctWords = Arrays.stream(words).distinct().toArray(String[]::new);
// Print the distinct words
System.out.println(Arrays.toString(distinctWords));
Try this:
public static int countUniqueWords(String words) {
// Add all the words to a list
List<String> array = new ArrayList<>();
Scanner in = new Scanner(words);
while (in.hasNext()) {
String s = in.next();
array.add(s);
}
// Save per word the amount of duplicates
HashMap<String, Integer> listOfWords = new HashMap<>();
Iterator<String> itr = array.iterator();
while (itr.hasNext()) {
String next = itr.next();
String prev = listOfWords.getOrDefault(next, 0);
listOfWords.put(next, prev + 1);
}
// Grab the size of all known words
return listOfWords.size();
}
public static void main(String args[]) {
int count = countUniqueWords("A long long time ago, I can still remember");
System.out.println("The number of unique words: " + count);
}
Related
The code here only shows how many words they are, how do i ignore the words that are the same?
For example, "A long long time ago, I
can still remember", would return 8 instead of 9.
I want it to be a method which takes one parameter s of
type String and returns an int value. And im only allowed to use the bacics, so no hash keys or hash set and advance stuff.
public static int mostCommonLetter(String s){
int wordCount = 0;
boolean word = false;
int endOfLine = s.length() - 1;
for (int i = 0; i < s.length(); i++) {
if (Character.isLetter(s.charAt(i)) && i != endOfLine) {
word = true;
} else if (!Character.isLetter(s.charAt(i)) && word) {
wordCount++;
word = false;
} else if (Character.isLetter(s.charAt(i)) && i == endOfLine) {
wordCount++;
}
}
return wordCount;
}
}
How do i ignore the words that are the same?
import java.util.*;
public class MyClass {
public static void main(String args[]) {
String input = "A long long time ago, I can still remember";
String[] words = input.split(" ");
List<String> uniqueWords = new ArrayList<>();
for (String word : words) {
if (!uniqueWords.contains(word)) {
uniqueWords.add(word);
}
}
System.out.println("Number of unique words: " + uniqueWords.size());
}
}
Output: Number of unique words: 8
Basically, what you can do if you're allowed to use data structures like lists and so on, is create a list and put the words of the input sentence in the list if and only if they aren't already there.
General idea:
public int getUniqueWords(String input) {
// Split the string into words using the split() method
String[] words = input.split(" ");
// Create a Set to store the unique words
Set<String> uniqueWords = new HashSet<String>();
// Loop through the words and add them to the Set
for (String word : words) {
uniqueWords.add(word);
}
// Return unique words amount
return uniqueWords.size();
}
Same solution using StreamAPI:
public int getUniqueWords2(String input) {
// here we can safely cast to int, because String can contain at most "max int" chars
return (int) Arrays.stream(input.split(" ")).distinct().count();
}
If it is needed to handle multiple spaces between words, add some cleanup for input:
// remove leading and trailing spaces
cleanInput = input.trim();
// replace multiple spaces with a single space
cleanInput = cleanInput.replaceAll("\\s+", " ");
Considering the requirement "allowed to use the bacics":
hashtable (HashSet) is a basic data structure in algorithms
problem of counting unique items cannot be logically solved without a container holding "aready seen" items, so algorithm could check whether the next item is counted or not
in the role of container in the simplest case could be a list, but that would cause O(n^2) time complexity.
You can use a Set<T> collection type, that can only contains unique values:
public static int getTotalUniqueWords(String input) {
String[] words = input.split(" ");
Set<String> uniqueWords = new HashSet<>();
Collections.addAll(uniqueWords, words);
return uniqueWords.size();
}
or with Streams:
public static long getTotalUniqueWordsStream(String input) {
String[] words = input.split(" ");
return Arrays.stream(words).distinct().count();
}
Im currently trying to create a function where my input is a string such as "AABBCCDDEE" and the function outputs a String array "AA""BB""CC" and so on.
public static char[] stringSplitter(final String input) {
String[] strarray = new String[input.length()];
if (input == null) {
return null;
}
char[] chrarray = input.toCharArray();
char[] outputarray = new char[input.length()];
int j = 0;
for (int i = 0; i < chrarray.length; i++) {
char chr = chrarray[i];
System.out.print(chr);
outputarray[j] = chrarray[i]; //here i need to find a way to add the characters to the index at j if the preceding characters are equal
if (i + 1 < input.length() && chrarray[i + 1] != chr) {
j++;
outputarray[j] = chrarray[i + 1];
System.out.println(" ");
}
}
}
Arrays are fixed-length, so you can't do this with an array unless you allocate one with sufficient extra room up-front (which would require a pass through the string to find out how much extra room you needed).
Instead, consider using a StringBuilder for the output, which you can convert into a char array when you're done.
If I understood correctly, you want to split the characters in a string so that similar-consecutive characters stay together. If that's the case, here is how I would do it:
public static ArrayList<String> splitString(String str) {
ArrayList<String> output = new ArrayList<>();
String combo = "";
//iterates through all the characters in the input
for(char c: str.toCharArray()) {
//check if the current char is equal to the last added char
if(combo.length() > 0 && c != combo.charAt(combo.length() - 1)) {
output.add(combo);
combo = "";
}
combo += c;
}
output.add(combo); //adds the last character
return output;
}
Note that instead of using an array (has a fixed size) to store the output, I used an ArrayList, which has a variable size. Also, note that it's a list of strings (stores strings), not characters. The reason for this is that if it was a list of characters I wouldn't be able to store more than one character in the same index.
In each iteration of the loop, I check for equality between the current character and it's consecutive. The variable combo is used to temporarily store the characters (in a string) before they go to output.
Now, to print the results in a clear way:
public static void main(String[] args)
{
String input = "EEEE BCD DdA";
ArrayList<String> output = splitString(input);
System.out.print("[");
for(int i = 0; i < output.size(); i++) {
System.out.print("\"" + output.get(i) + "\"");
if(i != output.size()-1)
System.out.print(", ");
}
System.out.println("]");
}
The output when running the above code will be:
["EEEE", " ", "B", "C", "D", " ", "D", "d", "A"]
You can use an ArrayList of type String to store the consecutive letter Strings after splitting them. This code should work for you.
import java.util.*;
public class StringSplitter{
static ArrayList<String> splitString(String str)
{
ArrayList<String> result_list= new ArrayList<String>();
int last_index;
if(str == null)
{
return null;
}
else
{
while(str.length() != 0)
{
last_index = str.lastIndexOf(str.charAt(0));
result_list.add(str.substring(0, last_index+1));
str = str.substring(last_index+1);
}
}
return result_list;
}
public static void main(String[] args)
{
ArrayList<String> result = splitString("AABBCCDDEEE");
System.out.println(result);
}
}
I have used an ArrayList because it does not require you to fix a size while declaration.
Edit:
I've tried to compile all of the code into a single program. Now all I need is to figure out how to return the modified string from the method. What do I have to put in order to achieve this?
Here's the new code:
public class String_Fixer {
public static void main(String[] args) {
String userInput, newString;
Scanner keyboard = new Scanner(System.in);
System.out.println("This program takes sentences and capitalizes them for you.");
System.out.println("Please write a few sentences.");
System.out.println("");
userInput = keyboard.nextLine();
System.out.println("");
System.out.println("Here is the original sentence:");
System.out.println(userInput);
System.out.println("");
System.out.println("And here is the modified sentence:");
System.out.println();
}
public static List<Integer> stringFixer(String userInput) {
List<Integer> indexes = new ArrayList<>();
int first = 0, offset = 2, index, offset_index;
while ((index = userInput.indexOf('.', first)) != -1) {
offset_index = index + offset;
if (offset_index < userInput.length()) {
indexes.add(offset_index);
}
first = index + 1;
}
while ((index = userInput.indexOf('?', first)) != -1) {
offset_index = index + offset;
if (offset_index < userInput.length()) {
indexes.add(offset_index);
}
first = index + 1;
}
return indexes;
}
public static String CapatilizeChars(List<Integer> indexes, String string) {
StringBuilder newString = new StringBuilder(string);
for (int i : indexes) {
char capChar = Character.toUpperCase(newString.charAt(i));
newString.setCharAt(i, capChar);
}
return newString.toString();
}
}
Use the Character.toUpperCase(CHARACTER); method to get the upper case variant of a character.
See this post: Indexes of all occurrences of character in a string for information on finding all indexes of a character in a String.
EDIT:
Here's how I would tackle the problem. First get the indexes that need to be changed using this method:
public static List<Integer> getIndexesOf(String regex, String stringToCheck, int offset) {
List<Integer> indexes = new ArrayList<>();
// Where to begin each indexof operation
int first = 0;
// The direct indexof result
int index;
// The indexof result offset by the specified amount
int offset_index;
// While we are still getting results from index of, save result under index and loop
while ((index = stringToCheck.indexOf(regex, first)) != -1) {
offset_index = index + offset;
// If the offset index doesn't excede the strings length add it to list
if (offset_index < stringToCheck.length()) {
indexes.add(offset_index);
}
first = index + 1;
}
return indexes;
}
Then capitalize each index using this method:
public static String CapatilizeChars(List<Integer> indexes, String string) {
StringBuilder newString = new StringBuilder(string);
// For each index capatilize the specified char
for (int i : indexes) {
char capChar = Character.toUpperCase(newString.charAt(i));
newString.setCharAt(i, capChar);
}
return newString.toString();
}
This isn't the fastest way of doing it, but it has the benefit of the method being more useful then a specific capitalize_char_after_regex method. You could easily combine this into one method by taking the code within the for loop of the second method and putting it into the first.
EDIT 2:
Fix for your updated code:
Replace: StringFixer modifiedString = new StringFixer();
With: String modifiedString = StringFixer.CapatilizeChars(StringFixer.getIndexesOf(userInput), userInput);
And remove the regex parameter from the getIndexesOf method since you aren't using them in your application.
The methods I gave you are static, which means they are not associated with an instance of an object. In other words, you don't need to construct the StringFixer class to use them.
I've been looking and I can't find anywhere how to write a word count using 3 methods. Here is what the code looks like so far. I'm lost on how to use the methods. I can do this without using different methods and just using one. Please help!!!
public static void main(String[] args) {
Scanner in = new Scanner (System.in);
System.out.print("Enter a string: ");
String s = in.nextLine();
if (s.length() > 0)
{
getInputString(s);
}
else
{
System.out.println("ERROR - string must not be empty.");
System.out.print("Enter a string: ");
s = in.nextLine();
}
// Fill in the body with your code
}
// Given a Scanner, prompt the user for a String. If the user enters an empty
// String, report an error message and ask for a non-empty String. Return the
// String to the calling program.
private static String getInputString(String s) {
int count = getWordCount();
while (int i = 0; i < s.length(); i++)
{
if (s.charAt(i) == " ")
{
count ++;
}
}
getWordCount(count);
// Fill in the body
// NOTE: Do not declare a Scanner in the body of this method.
}
// Given a String return the number of words in the String. A word is a sequence of
// characters with no spaces. Write this method so that the function call:
// int count = getWordCount("The quick brown fox jumped");
// results in count having a value of 5. You will call this method from the main method.
// For this assignment you may assume that
// words will be separated by exactly one space.
private static int getWordCount(String input) {
// Fill in the body
}
}
EDIT:
I have changed the code to
private static String getInputString(String s) {
String words = getWordCount(s);
return words.length();
}
private static int getWordCount(String s) {
return s.split(" ");
}
But I can't get the string convert to integer.
You have read the name of the method, and look at the comments to decide what should be implemented inside the method, and the values it should return.
The getInputString method signature should be:
private static String getInputString(Scanner s) {
String inputString = "";
// read the input string from system in
// ....
return inputString;
}
The getWordCount method signature should be:
private static int getWordCount(String input) {
int wordCount = 0;
// count the number of words in the input String
// ...
return wordCount;
}
The main method should look something like this:
public static void main(String[] args) {
// instantiate the Scanner variable
// call the getInputString method to ... you guessed it ... get the input string
// call the getWordCount method to get the word count
// Display the word count
}
count=1 //last word must be counted
for(int i=0;i<s.length();i++)
{
ch=s.charAt(i);
if(ch==' ')
{
count++;
}
}
Use trim() and split() on 1-n whitespace chars:
private static int getWordCount(String s) {
return s.trim().split("\\s+").length;
}
The call to trim() is necessary, otherwise you'll get one extra "word" if there is leading spaces in the string.
The parameter "\\s+" is necessary to count multiple spaces as a single word separator. \s is the regex for "whitespace". + is regex for "1 or more".
What you need to do is, count the number of spaces in the string. That is the number of words in the string.
You will see your count will be off by 1, but after some pondering and bug hunting you will figure out why.
Happy learning!
You can do this by :
private static int getWordCount(String input) {
return input.split("\\s+").length;
}
Use String.split() method like :
String[] words = s.split("\\s+");
int wordCount = words.length;
I'm not sure what trouble you're having with methods but I dont think you need more than one, try this: it uses split to split up the words in a string, and you can chose the delimeters
String sentence = "This is a sentence.";
String[] words = sentence.split(" ");
for (String word : words) {
System.out.println(word);
}
then you can do:
numberOfWords = words.length();
if you want to use 3 methods, you can call a method from your main() method that does this for you, for example:
public String getInputString() {
Scanner in = new Scanner (System.in);
System.out.print("Enter a string: ");
String s = in.nextLine();
if (s.length() > 0) {
return s;
} else {
System.out.println("ERROR - string must not be empty.");
System.out.print("Enter a string: ");
return getInputString();
}
}
public int wordCount(String s) {
words = splitString(s)
return words.length();
}
public String[] splitString(String s) {
return s.split(" ");
}
Based on your code i think this is what you're trying to do:
private static int getWordCount(String input) {
int count = 0;
for (int i = 0; i < input.length(); i++) {
if (input.charAt(i) == ' ') {
count++;
}
}
return count;
}
Here's what I've done:
I've moved the code you were 'playing' with into the right method (getWordCount).
Corrected the loop you were trying to use (I think you have for and while loops confused)
Fixed your check for the space character (' ' not " ")
There is a bug in this code which you'll need to work out how to fix:
getWordCount("How are you"); will return 2 when it should be 3
getWordCount(""); will return 0
getWordCount("Hello"); will return 0 when it should be 1
Good luck!
Better use simple function of spilt() with arguments as space
int n= str.split(" ").length;
public static int Repeat_Words(String arg1,String arg2)
{
//It find number of words can be formed from a given string
if(arg1.length() < 1 || arg2.length() < 1)
return 0;
int no_words = 99999;
char[] str1 = arg1.toCharArray();
char[] str2 = arg2.toCharArray();
for(int x = 0; x < str1.length; x++)
{
int temp = 0;
for(int y = 0; y < str2.length; y++)
{
if(str1[x] == str2[y])
temp++;
}
if(temp == 0)
return 0;
if(no_words > temp)
no_words = temp;
temp = 0;
}
return no_words;
}
I was given this problem to solve. I have only the slightest idea on how it should be implemented, and I'm all too new with programming and stuffs, and would love to hear your comments on this.
Say given a string in the form "abc1234defgh567jk89", and I must create a new string "a1b2c3d5e6f7j8k9".
Note that there are corresponding [digits] & [characters] group and since there may be more of one type over the other, the output has only matching sequence and ignore extra digits or characters in this case '4' & 'g' & 'h'.
I know I will have to use 2 sets of queues to store both types of elements, but I do not know how else to proceed from here.
Would appreciate if you could share a pseudocode or a Java(prefably) version, since I am learning thru this language now.
Thank you.
Pseudocode:
Queue letterQueue;
Queue numberQueue;
for (every character in the string) {
if (it's a letter) {
if (numberQueue is not empty) {
add the letters alternating into the buffer (stringbuilder), and purge buffers
}
add newest letter to letterqueue
}
if (it's a number) {
add newest letter to numberqueue
}
}
add any remaining unprocessed letters to the queue (this will happen most of the time)
return contents of string buffer
You will need:
Queue, probably a LinkedList
StringBuilder
String.toCharArray
Character
Code:
import java.util.LinkedList;
import java.util.Queue;
public class StringTest {
private static String str ="abc1234defgh567jk89";
private static String reorganize(String str) {
Queue<Character> letterQueue = new LinkedList<>();
Queue<Character> numberQueue = new LinkedList<>();
StringBuilder s = new StringBuilder();
for (char c : str.toCharArray()) {
if(Character.isLetter(c)) {
if (!numberQueue.isEmpty()) processQueues(letterQueue, numberQueue, s);
letterQueue.offer(c);
} else if(Character.isDigit(c)) {
numberQueue.offer(c);
}
}
processQueues(letterQueue, numberQueue, s);
return s.toString();
}
private static void processQueues(Queue<Character> letterQueue, Queue<Character> numberQueue, StringBuilder s) {
while(!letterQueue.isEmpty() && !numberQueue.isEmpty()) {
s.append(letterQueue.poll());
s.append(numberQueue.poll());
}
letterQueue.clear();
numberQueue.clear();
}
public static void main(String... args) {
System.out.println(reorganize(str));
}
}
See this hint:
String str = "abc1234defgh567jk89";
String c = str.replaceAll("\\d", ""); // to store characters
String d = str.replaceAll("\\D", ""); // to store digits
Try this:
public static void main(String[] args) {
String str = "abc1234defgh567jk89";
String c = str.replaceAll("\\d", "");
String d = str.replaceAll("\\D", "");
String result = "";
int j = 0, k = 0;
int max = Math.max(c.length(), d.length());
for (int i = 0; i < max; i++) {
if (j++ < c.length())
result = result + c.charAt(i);
if (k++ < d.length())
result = result + d.charAt(i);
}
System.out.println(result);
}
Output:
a1b2c3d4e5f6g7h8j9k