How to eliminate a nested for loop to get O(n)? - java

In the code below I have a double for loop resulting in a time complexity of O^2 in method getResponse(). This code prompts the user for a 10 integer sequence string and an uppercase sensitive pin. It then converts the pin to numbers on a phone pad ie. [ABC] --> 2, [DEF] --> 3. Lastly a response array is generated with each digit of the new phone pin corresponding to indexes of sequence. So input "0123456789","HAM", response = "426"
import java.util.Scanner;
public class Test {
public static final int SEQ_DIGITS = 10;
public static final String ERR_SEQ = "Invalid sequence";
public static final String ERR_PIN = "Invalid PIN";
public static int letterToPhone(char c) {
int phoneNumber = 0;
if (Character.toString(c).matches("[ABC]")) {
phoneNumber = 2;
} else if (Character.toString(c).matches("[DEF]")) {
phoneNumber = 3;
} else if (Character.toString(c).matches("[GHI]")) {
phoneNumber = 4;
} else if (Character.toString(c).matches("[JKL]")) {
phoneNumber = 5;
} else if (Character.toString(c).matches("[MNO]")) {
phoneNumber = 6;
} else if (Character.toString(c).matches("[PQRS]")) {
phoneNumber = 7;
} else if (Character.toString(c).matches("[TUV]")) {
phoneNumber = 8;
} else if (Character.toString(c).matches("[WXYZ]")) {
phoneNumber = 9;
}
return phoneNumber;
}
public static int[] getResponse(String pin, int[] values) {
int[] response = new int[pin.length()];
for(int i = 0; i < pin.length(); i++) {
for (int j = 0; j < values.length; j++) {
int x = letterToPhone(pin.charAt(i));
if(x == j) {
response[i] = values[j];
}
}
}
return response;
}
public static boolean stringIsLengthK(String s, int k) {
boolean isLength = false;
if (s.length() == k) {
isLength = true;
}
return isLength;
}
public static boolean allDigits(String s) {
boolean isDigit = true;
for (int i = 0; i < s.length(); i++) {
if (!(Character.isDigit(s.charAt(i)))) {
isDigit = false;
break;
}
}
return isDigit;
}
public static boolean allUppercaseLetters(String s) {
boolean isUpper = true;
for (int i = 0; i < s.length(); i++) {
if (!(Character.isUpperCase(s.charAt(i)))) {
isUpper = false;
break;
}
}
return isUpper;
}
public static int[] digitStringToIntArray(String s) {
int[] arrayS = new int[s.length()];
for(int i = 0; i < arrayS.length; i++) {
for(int j = 0; j < SEQ_DIGITS; j++) {
if (((int) s.charAt(i) - 48) == j) {
arrayS[i] = j;
}
}
}
return arrayS;
}
public static int countValues(int value, int[] values) {
int count = 0;
for(int i = 0; i < values.length; i++) {
if(value == values[i]) {
count++;
}
}
return count;
}
public static int numPossible(int[] response, int[] values) {
int product = 1;
int[] count = new int[response.length];
for (int i = 0; i < count.length; i++) {
count[i] = countValues(response[i], values);
}
for(int i=0; i<response.length; i++){
product = product * count[i];
}
return product;
}
public static void main(String[] args) {
try (Scanner in = new Scanner(System.in)) {
System.out.printf("Enter value sequence: ");
final String seq = in.nextLine();
System.out.printf("Enter PIN: ");
final String pin = in.nextLine();
if (!(allUppercaseLetters(pin))) {
throw new AssertionError(ERR_PIN);
} else if (!(allDigits(seq)) || !(stringIsLengthK(seq, SEQ_DIGITS))) {
throw new AssertionError(ERR_SEQ);
}
int[] seqArray = new int[SEQ_DIGITS];
seqArray = digitStringToIntArray(seq);
int[] response = new int[SEQ_DIGITS];
response = getResponse(pin, seqArray);
System.out.printf("Response: ");
for (int i = 0; i < response.length; i++) {
System.out.printf("%d", response[i]);
}
System.out.printf("%n");
numPossible(response, seqArray);
} catch (Error e) {
System.out.println(e.getMessage());
}
}
}
I want to be to able to accommodate larger sequence numbers without a scaling of n^2. Is there a way to change the for loop to instead compare the int x = letterToPhone(pin.charAt(i)); value in getResponse() to a range of integers such as "[0-9]"

One easy optimization of constant factors is to move the call to letterToPhone() out of the inner loop.
And yes, you can compare the x value to a range, eliminating the need for the inner loop.
for(int i = 0; i < pin.length(); i++) {
int x = letterToPhone(pin.charAt(i));
if ( (0 <= x) && (x < values.length)) {
response[i] = values[x];
}
}
Another optimization of constant factors would be to replace all the function calls in letterToPhone() with a switch statement. The compiler may choose to optimize that into a table lookup.

Related

The longest common subsequence for n string in java without using libraries?

I am trying to find a simple solution and I have read all the information or question that try to answer or have solve the problem , and i have being testing.
I have found a solution which i converted from c#, and it works, but is too complicated and i do not understand how it works, so i was trying to make my own solution.
public static String lcs(String[] strings) {
if (strings.length == 0)
return "0";
if (strings.length == 1)
return strings[0];
int max = -1;//max length of a string
int cacheSize = 1; //multiplied length size of array with each other.
for (int i = 0; i < strings.length; i++) {
cacheSize *= strings[i].length();
if (strings[i].length() > max)
max = strings[i].length();
}
String[] cache = new String[cacheSize];
int[] indexes = new int[strings.length];
for (int i = 0; i < indexes.length; i++)
indexes[i] = strings[i].length() - 1;
return lcsBack(strings, indexes, cache);
}
public static String lcsBack(String[] strings, int[] indexes, String[] cache) {
for (int i = 0; i < indexes.length; i++)
if (indexes[i] == -1)
return "";
boolean match = true;
for (int i = 1; i < indexes.length; i++) {
if (strings[0].charAt(indexes[0]) != strings[i].charAt(indexes[i])) {
match = false;
break;
}
}
if (match) {
int[] newIndexes = new int[indexes.length];
for (int i = 0; i < indexes.length; i++)
newIndexes[i] = indexes[i] - 1;
String result = lcsBack(strings, newIndexes, cache) + strings[0].charAt(indexes[0]);
cache[calcCachePos(indexes, strings)] = result;
return result;
} else {
String[] subStrings = new String[strings.length];
for (int i = 0; i < strings.length; i++) {
if (indexes[i] <= 0)
subStrings[i] = "";
else {
int[] newIndexes = new int[indexes.length];
for (int j = 0; j < indexes.length; j++)
newIndexes[j] = indexes[j];
newIndexes[i]--;
int cachePos = calcCachePos(newIndexes, strings);
if (cache[cachePos] == null)
subStrings[i] = lcsBack(strings, newIndexes, cache);
else
subStrings[i] = cache[cachePos];
}
}
String longestString = "";
int longestlength = 0;
for (int i = 0; i < subStrings.length; i++) {
if (subStrings[i].length() > longestlength) {
longestString = subStrings[i];
longestlength = longestString.length();
}
}
cache[calcCachePos(indexes, strings)] = longestString;
return longestString;
}
}
static int calcCachePos(int[] indexes, String[] strings) {
int factor = 1;
int pos = 0;
for (int i = 0; i < indexes.length; i++) {
pos += indexes[i] * factor;
factor *= strings[i].length();
}
return pos;
}
So on what i understand i have being able, to make this method which is simple, but still doesn't work.
And i know from readings that the best way to solve this is using dinamic programming I would appreciate if somebody can help, thank you
/**
* #param strArr .
* #return String
*/
public String findCommonString(String[] words) throws Exception {
try {
String commonStr = "";
String tempCom = "";
char[] longestWordChars = findTheLongestString(words).toCharArray();
for (char c : longestWordChars) {
tempCom += c;
for (String word : words) {
if (!word.contains(tempCom)) {
tempCom = Character.toString(c);
for (String word2 : words) {
if (!word2.contains(tempCom)) {
tempCom = "";
break;
}
}
break;
}
}
if (tempCom != "" && tempCom.length()>commonStr.length()) {
commonStr = tempCom;
//strArr = removeFirstOccurrence(strArr, tempCom);
// tempCom = "";
}
}
return commonStr;
} catch (Exception e) {
logger.warn("[findCommonString] [STATUS] - ERROR ");
logger.warn("[findCommonString] [EXCEPTION] " + e.getMessage());
throw e;
}
/**
* #param strArr .
* #return String
*/
public String findTheLongestString(String[] words) throws Exception { // test
try {
String longestWord = "";
for (String s : words) {
if (longestWord.length() < s.length()) {
longestWord = s;
}
}
return longestWord;
} catch (Exception e) {
logger.warn("[findTheLongestString] [STATUS] - ERROR ");
logger.warn("[findTheLongestString] [EXCEPTION] " + e.getMessage());
throw e;
}
}
I have being testing with this two test unit example
#Test
public void SubsequenceServiceTest3() throws Exception {
assertEquals("CDAC", subsequenceService.findCommonSequence(new String[] { "BCDAACD", "ACDBAC" }));
}
#Test
public void SubsequenceServiceTest14() throws Exception {
assertEquals("CA", subsequenceService.findCommonSequence(new String[] { "ACADB", "CBDA" }));
}

Why else statement is executing although if statement is true?

import java.util.Scanner;
class candidate {
public String name;
public int count;
public candidate(String name) {
super();
this.name = name;
}
}
public class DayScholar {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
candidate[] candidates = new candidate[3];
candidates[0] = new candidate("vikas");
candidates[1] = new candidate("ganesh");
candidates[2] = new candidate("teja");
System.out.print("No. of voters : ");
int voters = in.nextInt();
in.nextLine();
for (int i = 0; i < voters; i++) {
System.out.print("vote : ");
String name = in.nextLine().toLowerCase();
for (int j = 0; j < 3; j++) {
Here is the code, although if the statement is true else is also executing. How to check the condition
if (name.equals(candidates[j].name)) {
candidates[j].count++;
} else { **//problem here**
System.out.println("N");
break;
}
}
}
int highest = 0;
String winner = "";
for (int i = 0; i < 3; i++) {
if (candidates[i].count > highest) {
highest = candidates[i].count;
winner = candidates[i].name;
} else if (candidates[i].count == highest) {
winner += ("\n" + candidates[i].name);
}
}
System.out.println(winner);
}
}
Assuming the user enters a valid name, the following loop will increment the count field on the candidate with the matching name, and print N for the other 2 candidates.
for (int j = 0; j < 3; j++) {
if (name.equals(candidates[j].name)) {
candidates[j].count++;
} else {
System.out.println("N");
break;
}
}
To fix, you need the loop to just set the index of the matching candidate, then do the increment or printing after the loop:
int matchingIndex = -1; // -1 = not found
for (int j = 0; j < 3; j++) {
if (name.equals(candidates[j].name)) {
matchingIndex = j;
break;
}
}
if (matchingIndex == -1) {
System.out.println("N");
} else {
candidates[matchingIndex].count++;
}

count repeat of every word

I want to write a code that count repeat of every word in a string,words separate each other with some character that input as a string...why my code don't work?
please answer soon!
public class repeat {
public static void main(String[] args) {
Scanner ss = new Scanner(System.in);
System.out.println("Please write a string:");
String s = ss.nextLine();
System.out.println("Please write a character:");
String w = ss.nextLine();
int i = 0;
int j = 0;
int k = 0;
int y=0;
for (i=0 ;i < s.length() ;i++) {
for (j = 0; j < w.length(); j++) {
if (w.charAt(j) == s.charAt(i) && i!=y && i!=0 && i!=s.length() -1 ) {
k += 1;
y=i+1;
}
}
}
i = 0;
j = 0;
y = 0;
int r = 0;
k++;
System.out.println(k);
String[] a = new String[k];
for (r=0 ;r < k-1 ;r++) {
for (j=1 ;j < s.length() ;j++) {
for (i = 1; i < w.length(); i++) {
if (w.charAt(i) == s.charAt(j)) {
a[r] = s.substring(y, j);
y = j+1;
}
}
}
System.out.println(a[r]);
}
a[k-1] = s.substring(y+1,s.length());
i = 0;
int[] b = new int[k];
while (i <k) {
b[i] = 0;
i++;
}
i = j = 0;
while (i < k) {
while (j != i && j < k) {
if (a[i] == a[j]) {
a[j] = null;
b[i]++;
}
j++;
}
i++;
}
i = j = 0;
while (i < k) {
if (a[i] != null) {
System.out.println(a[i] + " " + b[i]);
}
i++;
}
}
}
Looking through your code your taking a very long approach to this problem. The easiest thing to do is use regex https://docs.oracle.com/javase/tutorial/essential/regex/. Please see the methods below.
public Sentence(String sentanceString) {
this.fullSentence = sentanceString;
breakStringIntoWords(sentanceString);
}
private void breakStringIntoWords(String sentanceString) {
String[] wordsInString = sentanceString.split("\\W+");
for (String word : wordsInString) {
words.add(new Word(word));
}
}
In the second method I broke a sentence (delimited by [spaces]) into words. From here you would write code to compare each word (a class that has a to string method so treat it as a string) to every other word in the Words array list, be careful to avoid over counting.
ok this is now Java with Split instead of searching the string manually:
I don't exactly know if the copyarray is the best practice to make it larger but if your string is not megabytes large it won't be a problem:
public class repeat
{
public static void main(String[] args)
{
String s = "Hello world this is a very good test to a world just that contains just more words than just hello";
String w = " ";
String[] foundwords = new String[0];
int[] wordcount = new int[0];
String[] splittext = s.split(w);
for (int i = 0; i< splittext.length; i++)
{
int IndexOfWord = getIndexOfWord(splittext[i], foundwords);
if (IndexOfWord < 0)
{
String[] foundwordsTemp = new String[foundwords.length + 1];
int[] wordcountTemp = new int[foundwords.length + 1];
System.arraycopy(foundwords, 0, foundwordsTemp, 0, foundwords.length);
System.arraycopy(wordcount, 0, wordcountTemp, 0, foundwords.length);
foundwords = new String[foundwords.length + 1];
wordcount = new int[wordcount.length + 1];
System.arraycopy(foundwordsTemp, 0, foundwords, 0, foundwordsTemp.length);
System.arraycopy(wordcountTemp, 0, wordcount, 0, foundwordsTemp.length);
foundwords[foundwords.length-1] = splittext[i];
wordcount[foundwords.length-1] = 1;
}
else
{
wordcount[IndexOfWord]++;
}
}
for (int i = 0; i < foundwords.length; i++)
{
System.out.println(String.format("Found word '%s' %d times.", foundwords[i], wordcount[i]));
}
}
private static int getIndexOfWord(String word, String[] foundwords)
{
for (int i = 0; i < foundwords.length; i++)
{
if (word.equals(foundwords[i]))
{
return i;
}
}
return -1;
}
}
(Wrong language i did it wrongly in c# - see next answer for java)
I suggest to use array and Split for this because it is very complicated work with substring to seach for the char. While w still is a String, c need to be a type char.
String[] foundwords = { };
Int32[] wordcount = { };
foreach (String word in s.Split(w))
{
int IndexOfWord = Array.IndexOf(foundwords, word);
if (IndexOfWord < 0)
{
Array.Resize(ref foundwords, foundwords.Length + 1);
Array.Resize(ref wordcount, wordcount.Length + 1);
foundwords[foundwords.GetUpperBound(0)] = word;
wordcount[foundwords.GetUpperBound(0)] = 1;
}
else
{
wordcount[IndexOfWord]++;
}
}
for (int i = 0; i <= foundwords.GetUpperBound(0); i++)
{
Console.WriteLine(String.Format("Found word '{0}' {1} times.", foundwords[i], wordcount[i]));
}
be aware that it is case sensitive.
so if it is still on your list i made a code.
First - you where lost to just let it run in the main procedure only. You should start and seperate your work into single tasks instead of writing a strait start stop program. Using functions with a "good" name will make it easier to you in future.
First you need something to find the String in another.
Usually you may use
int dividerPosition = restString.indexOf(searchString);
this is a java build in function. If you want to write it yourself, you could create a function like this (that will do the same but you can "see" it working:)
private static int indexOf(String restString, String searchString)
{
int dividerPosition = -1;
for (int i = 0; i < restString.length()-searchString.length(); i++)
{
// Debuging test:
System.out.println(String.format("search Pos %d in '%s' for length %d.", i, restString, searchString.length()));
if (restString.substring(i, i + searchString.length()).equals(searchString))
{
dividerPosition = i;
i = restString.length();
}
}
return dividerPosition;
}
and use this function in your code later on like:
int dividerPosition = indexOf(restString, searchString);
I will again use the function to find either a word is allready known
private static int getIndexOfWord(String word, String[] foundwords)
{
for (int i = 0; i < foundwords.length; i++)
{
if (word.equals(foundwords[i]))
{
return i;
}
}
return -1;
}
Third Task would be to Split and count the Words at the found position.
The easier way (only my opinion) would be just to cut of the found Words from the String - so write a function that will "save" the found word in a array or count the "counter"-Array if it is allready found.
This most important task to understand is important - ok we will just look for the position of the string we are searching. We need to check if it is not found (so the last word)
We will store the found word (that is the part before the found String) in a variable and do the "count or create new word" thing. And then we will return the String cut of the word and the Seach-String.
The Cut-Off is important because we replace the origin String by the one without the first word and just repeat this until the origin String is "".
For the last word we ensure the function will return "" by changing the dividerPosition to the length of the RestString - that is the last word now only - minus "searchString.length()" so it will fit to the return "restString.substring(dividerPosition+searchString.length());" to return ""
Look in the next part into the function named "getNextW("
you can run int with the self-written IndexOf function or the Java function by changing the commentlines in
/// Index Of Search (better)
//int dividerPosition = restString.indexOf(searchString);
/// Manual Search (why make it more difficuilt - you should learn to make your work as easy as possible)
int dividerPosition = indexOf(restString, searchString);
Everything together
to get startet you will have very little code in the main procedure using the "cut" function until the String is empty - all together now:
public class repeat
{
public static void main(String[] args)
{
String s = "Hello a world a this is a very good test to a a a a world just that contains just more words than just hello";
String w = " ";
while (!(s = getNextW(s, w)).equals(""))
{
System.out.println(s);
}
System.out.println("");
for (int i = 0; i < foundwords.length; i++)
{
// Debuging test:
System.out.println(String.format("Found word '%s' %d times.", foundwords[i], wordcount[i]));
}
}
private static String[] foundwords = new String[0];
private static int[] wordcount = new int[0];
private static String getNextW(String restString, String searchString)
{
/// Index Of Search (better)
//int dividerPosition = restString.indexOf(searchString);
/// Manual Search (why make it more difficuilt - you should learn to make your work as easy as possible)
int dividerPosition = indexOf(restString, searchString);
String foundWord;
if (dividerPosition > 0)
{
foundWord = restString.substring(0, dividerPosition);
}
else
{
foundWord = restString;
dividerPosition = restString.length()-searchString.length();
}
int IndexOfWord = getIndexOfWord(foundWord, foundwords);
if (IndexOfWord < 0)
{
String[] foundwordsTemp = new String[foundwords.length + 1];
int[] wordcountTemp = new int[foundwords.length + 1];
System.arraycopy(foundwords, 0, foundwordsTemp, 0, foundwords.length);
System.arraycopy(wordcount, 0, wordcountTemp, 0, foundwords.length);
foundwords = new String[foundwords.length + 1];
wordcount = new int[wordcount.length + 1];
System.arraycopy(foundwordsTemp, 0, foundwords, 0, foundwordsTemp.length);
System.arraycopy(wordcountTemp, 0, wordcount, 0, foundwordsTemp.length);
foundwords[foundwords.length-1] = foundWord;
wordcount[foundwords.length-1] = 1;
}
else
{
wordcount[IndexOfWord]++;
}
// Debuging test:
System.out.println(String.format("Rest of String is '%s' positionnext is %d.", restString, dividerPosition));
return restString.substring(dividerPosition+searchString.length());
}
private static int getIndexOfWord(String word, String[] foundwords)
{
for (int i = 0; i < foundwords.length; i++)
{
if (word.equals(foundwords[i]))
{
return i;
}
}
return -1;
}
private static int indexOf(String restString, String searchString)
{
int dividerPosition = -1;
for (int i = 0; i < restString.length()-searchString.length(); i++)
{
// Debuging test:
System.out.println(String.format("search Pos %d in '%s' for length %d.", i, restString, searchString.length()));
if (restString.substring(i, i + searchString.length()).equals(searchString))
{
dividerPosition = i;
i = restString.length();
}
}
return dividerPosition;
}
}
Other variant with charAt and im am using your kind of "count words to size the array" what will result in a to big array (potentially far to big):
public class repeat
{
private static String[] foundwords;
private static int[] wordcount;
private static int counter;
public static void main(String[] args) {
String s = "Hello a world a this is a very good test to a a a a world just that contains just more words than just hello";
String w = " ";
int tempPos = 0;
counter = 1; // counting total w-strings+1 for dim
while ((tempPos = findnext(s, w, tempPos)) >= 0)
{
tempPos = tempPos + w.length();
counter++;
}
foundwords = new String[counter];
wordcount = new int[counter];
counter = 0;
while ((tempPos = findnext(s, w, 0)) >= 0)
{
String foundWord = s.substring(0, tempPos);
s = s.substring(tempPos + w.length());
foundWordToArray(foundWord);
}
foundWordToArray(s);
for (int i = 0; i < counter; i++)
{
System.out.println(String.format("Found word '%s' %d times.", foundwords[i], wordcount[i]));
}
}
public static int findnext(String haystack, String needle, int startPos)
{
int hpos, npos;
for (hpos = startPos; hpos < haystack.length()-needle.length(); hpos++)
{
for (npos = 0; npos < needle.length(); npos++)
{
if (haystack.charAt(hpos+npos)!=needle.charAt(npos))
{
npos = needle.length()+1;
}
}
if (npos == needle.length())
{
return hpos;
}
}
return -1;
}
private static int getIndexOfWord(String word, String[] foundwords)
{
for (int i = 0; i < foundwords.length; i++)
{
if (word.equals(foundwords[i]))
{
return i;
}
}
return -1;
}
private static void foundWordToArray(String foundWord)
{
int IndexOfWord = getIndexOfWord(foundWord, foundwords);
if (IndexOfWord < 0)
{
foundwords[counter] = foundWord;
wordcount[counter] = 1;
counter++;
}
else
{
wordcount[IndexOfWord]++;
}
}
}
i like this one:
public class repeat
{
private static String[] foundwords = new String[0];
private static int[] wordcount = new int[0];
public static void main(String[] args) {
String s = "Hello a world a this is a very good test to a a a a world just that contains just more words than just hello";
String w = " ";
int tempPos;
while ((tempPos = findnext(s, w, 0)) >= 0)
{
String foundWord = s.substring(0, tempPos);
s = s.substring(tempPos + w.length());
foundWordToArray(foundWord);
}
foundWordToArray(s);
for (int i = 0; i < foundwords.length; i++)
{
System.out.println(String.format("Found word '%s' %d times.", foundwords[i], wordcount[i]));
}
}
private static void foundWordToArray(String foundWord)
{
int IndexOfWord = getIndexOfWord(foundWord, foundwords);
if (IndexOfWord < 0)
{
String[] foundwordsTemp = new String[foundwords.length + 1];
int[] wordcountTemp = new int[foundwords.length + 1];
System.arraycopy(foundwords, 0, foundwordsTemp, 0, foundwords.length);
System.arraycopy(wordcount, 0, wordcountTemp, 0, foundwords.length);
foundwords = new String[foundwords.length + 1];
wordcount = new int[wordcount.length + 1];
System.arraycopy(foundwordsTemp, 0, foundwords, 0, foundwordsTemp.length);
System.arraycopy(wordcountTemp, 0, wordcount, 0, foundwordsTemp.length);
foundwords[foundwords.length-1] = foundWord;
wordcount[foundwords.length-1] = 1;
}
else
{
wordcount[IndexOfWord]++;
}
}
public static int findnext(String haystack, String needle, int startPos)
{
int hpos, npos;
for (hpos = startPos; hpos < haystack.length()-needle.length(); hpos++)
{
for (npos = 0; npos < needle.length(); npos++)
{
if (haystack.charAt(hpos+npos)!=needle.charAt(npos))
{
npos = needle.length()+1;
}
}
if (npos == needle.length())
{
return hpos;
}
}
return -1;
}
private static int getIndexOfWord(String word, String[] foundwords)
{
for (int i = 0; i < foundwords.length; i++)
{
if (word.equals(foundwords[i]))
{
return i;
}
}
return -1;
}
}

Look for repeated characters in a string

I know this question was asked many times, but I didn't find any of the answers helpful in my case. I have a method that receives a String. I want to check if any of the characters in the string are repeated. If so the method will return an empty String. If not it will return the String back.
The method is looking for any repeated character in the String.
private String visit(String word) {
int count = 0;
if(word == ""){
return "<empty>";
}
//alphabet is an array that holds all characters that could be used in the String
for(int i = 0; i < alphabet.length; i++){
for(int j = 0; j < word.length(); j++){
if(alphabet[i] == word.charAt(j)){
count++;
}
if(count == 2){
return "";
}
}
count = 0;
}
return word;
}
Ok, I publish my solution to this:
package main;
import java.util.Arrays;
public class main {
public static void main(String[] args) {
System.out.println(hasDups("abc"));
System.out.println(hasDups("abcb"));
}
public static String hasDups(String arg) {
String[] ar = arg.split("");
Arrays.sort(ar);
boolean noDups = true;
for (int i = 1; i < ar.length && noDups; i++) {
if (ar[i].equals(ar[i-1])) noDups = false;
}
if (noDups) return arg; else return "";
}
}
This might not be the best way of doing what you want, but you can use two for loops to check each character against all the other characters to see if it is repeated.
public static String hasRepeated(String word) {
if (word.isEmpty()) return "<empty>";
char[] charArray = word.toCharArray();
for (int i = 0; i < charArray.length; i++) {
for (int j = 0; j < charArray.length; j++) {
if (i == j) {
} else if (Character.toString(charArray[i]).
equalsIgnoreCase(Character.toString(charArray[j]))) {
return "";
}
}
}
return word;
}
Note: This code assumes that the case of the character doesn't matter, it just checks if it is repeated.
/**
* Returns the index of the first character repeated, or -1 if no repeats
*/
public static int firstRepeated( String s ) {
if ( s != null ) {
int n = s.length();
for (int i = 0; i < (n - 1); i++) {
int indx = s.indexOf( s.charAt( i ), i + 1 );
if ( indx > 0 ) {
return i;
}
}
}
return -1;
}
This works!!
public static String checkDuplicate(String str)
{
int count = 0;
char[] charArray = str.toCharArray();
for(int i=0;i<charArray.length;i++)
{
count = 0;
for(int j=0;j<charArray.length;j++)
{
if(charArray[i]==charArray[j])
{
count++;
if(count==2) break;
}
}
if(count==2) break;
}
if(count==2)
return "";
else
return str;
}
}

How can I avoid repetition of the same number?

This is what I want :
Let the user enter as many numbers as they want until a non number is entered (you may
assume there will be less than 100 numbers). Find the most frequently entered number. (If
there are more than one, print all of them.)
Example output:
Input: 5
Input: 4
Input: 9
Input: 9
Input: 4
Input: 1
Input: a
Most common: 4, 9
I have got to the point in my code where I have managed to find out which are the most common numbers. However, I don't want to print out the same number over and over again; example from above: Most common: 4, 9, 9, 4
What needs to be done?
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String[] input = new String[100];
System.out.print("Input: ");
input[0] = in.readLine();
int size = 0;
for (int i = 1; i < 100 && isNumeric(input[i-1]); i++) {
System.out.print("Input: ");
input[i] = in.readLine();
size = size + 1;
}
/*for (int i = 0; i < size; i++) { //testing
System.out.println(input[i]);
}*/
int numOccur;
int[] occur = new int[size];
for(int i = 0; i < size; i++) {
numOccur = 0;
for (int j = 0; j < size; j++) {
if(input[i].equals(input[j])) {
numOccur = numOccur + 1;
}
}
occur[i] = numOccur;
//System.out.println(numOccur); //testing
}
int maxOccur = 0;
for(int i = 0; i < size; i++) {
if(occur[i] > maxOccur) {
maxOccur = occur[i];
}
}
//System.out.println(maxOccur); //testing
for (int i = 0; i < size && !numFound; i++) {
if(occur[i] == maxOccur) {
System.out.println(input[i]);
}
}
}
//checks if s is an in, true if it is an int
public static boolean isNumeric (String s) {
try {
Integer.parseInt(s);
return true; //parse was successful
} catch (NumberFormatException nfe) {
return false;
}
}
Found the solution!
String[] mostCommon = new String[size];
int numMostCommon = 0;
boolean numFound = false;
for (int i = 0; i < size; i++) {
int isDifferent = 0;
if (occur[i] == maxOccur) {
for (int j = 0; j < size; j++) {
if (!(input[i].equals(mostCommon[j]))) {
isDifferent = isDifferent + 1;
}
}
if (isDifferent == size) {
mostCommon[numMostCommon] = input[i];
numMostCommon = numMostCommon + 1;
}
}
}
for (int i = 0; i < numMostCommon - 1; i++) {
System.out.print("Most common: " + mostCommon[i] + ", ");
}
System.out.println(mostCommon[numMostCommon - 1]);
you could use the hash table for this to store the frequenceis as the limit is very less i.e. less than 100.
pseudo code would be like:
vector<int> hash(101)
cin>>input
if(isnumeric(input))
hash[input]++
else{
max=max_element(hash.begin(),hash.end());
for(int i=0;i<100;i++)
if(hash[i]==max)
print i
}
Set<Integer> uniqueMaxOccur = new HashSet<Integer>();
for (int i = 0; i < size ; i++) {
if(occur[i] == maxOccur) {
//System.out.println(input[i]);
uniqueMaxOccur.add(input[i]);
}
}
and display the values in the set
You can use a Set and store the values already printed.
What about something like this?
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
Map<string,int> numberLookup = new HashMap<string,int>();
Boolean doContinue = true;
while (doContinue)
{
System.out.print("Input: ");
String input = in.readLine();
if (isNumeric(input))
{
if (!numberLookup.containsKey(input))
numberLookup.put(input,1);
else
numberLookup.put(input, numberLookup.get(input) + 1);
}
else
doContinue = false;
}
maxOccur = numberLookup.values().max();
System.out.print("These numbers were all entered " + maxOccur + " times:");
Iterator it = numberLookup.entrySet().iterator();
while (it.hasNext())
{
(Map.Entry)it.next();
System.out.println(pairs.getKey());
}
}
Sorry, I'm a C# person and don't have a Java compiler on me, so this might need some tweaking.

Categories