To find smallest word in a string in java - java

This is the code that i have written for finding the smallest word in a string but whenever i try to run it in eclipse it shows me an (String index out of range -2147483648) error in nested while statement, that i had marked , i do not understand the cause of it since my program seems to be running well in the range i.e less than length of the input string.
Thanks in advance!!
import java.util.Scanner;
public class Minword {
public static String minLengthWord(String input){
// Write your code here
int count[]=new int[50],i,j=0,len=input.length();
String output = "";
for(i=0;i<len;i++)
{
if(input.charAt(i)!=' ')
{
count[j]++;
}
else
j++;
}
int minidx=0;
for(i=1;i<j;i++)
{
if(count[minidx]>count[i])
minidx=i;
}
int words=0;
i=0;
while(words<=minidx)
{
if(words==minidx)
{
***while(i<len && input.charAt(i)!=' ')***
{
output+=input.charAt(i);
i++;
}
}
else if(i<len && input.charAt(i)==' ')
words++;
i++;
}
return output;
}
public static void main(String[] args) {
Scanner s=new Scanner(System.in);
String input,output;
input=s.nextLine();
output=minLengthWord(input);
}
}

I have problems following your code, but to get the shortest word's length, you can use a Stream and min(). Your minLengthWord method could be like:
String f = "haha hah ha jajaja";
OptionalInt shortest = Arrays.stream(f.split(" ")).mapToInt(String::length).min();
System.out.println(shortest.getAsInt());

You are using the variable i, which is a signed int, so it ranges from -2147483648 to 2147483647.
The following case shows your problem:
i = 2147483647;
i++;
After the increment, i's value will be -2147483648 due to a int overflow. Check this question.
It seems you are getting a huge input, thus it is causing the problem.

Well, -2147483648 is the maximal integer + 1. You have a wrap around. The variable i got so big that it start on the negative side again.
You have to use a long if you want to process texts that are larger than 2 GB.

while(words<=minidx)
{
if(words==minidx)
{
***while(i<len && input.charAt(i)!=' ')***
{
output+=input.charAt(i);
i++;
}
}
else if(i<len && input.charAt(i)==' ')
words++;
i++;
}
Your problem is you when words and minidx are both 0, your outer while loop is always true and words are always equal to minidx, and i keeps increasing until reaches its maximum number.
you need to add break after your inner while loop and secondly, you need to change i<j to i<=j
Below is the corrected code:
int minidx = 0;
for (i = 1; i <= j; i++) { //-------------------------> change i<j to i<=j
if (count[minidx] > count[i])
minidx = i;
}
int words = 0;
i = 0;
System.out.println(minidx);
while (words <= minidx) {
if (words == minidx) {
while (i < len && input.charAt(i) != ' ') {
output += input.charAt(i);
i++;
}
break; //-------------------------> add break statement here.
} else if (i < len && input.charAt(i) == ' ') {
words++;
}
i++;
}

When I tried running your code with an input of "Hello World", minidx was 0 before the while loop. words is also 0, so words<=minidx is true and the loop is entered. words==minidx is true (they're both 0), so the if statement is entered. Because it never enters the else if (which is the only place words is changed), words is always 0. So the loop becomes an infinite loop. In the meantime, i just keeps growing, until it overflows and becomes negative.

Here's a version that makes use of Java 8's Stream API:
Remove all your code from minLengthWord Method and paste below code it will work and resolve your runtime issue too
List<String> words = Arrays.asList(input.split(" "));
String shortestWord = words.stream().min(
Comparator.comparing(
word -> word.length()))
.get();
System.out.println(shortestWord);

Related

how can i make a method that can count the amount of spaces in a string up to the first blank space?

#Test
public void testFirstBlankPosition()
{
assertEquals(4, sc1.firstBlankPosition());
assertEquals(5, sc2.firstBlankPosition());
}
This is what i have to try and run the test, but it doesn't fail the test but it doesn't pass it either, what is going wrong with this? It's supposed to count the amount of characters till the first blank space in the string and return the amount of spaces it was.
public Object firstBlankPosition()
{
int i = 0;
int count = 0;
while ( i < sentence.length())
if( sentence.charAt(i) != ' ')
{
count = count + 1;
}
else
{
i = i + 1;
}
return count;
}
You should use a for-loop instead. i should always be incremented.
for (int i = 0; i < sentence.length(); i++){
if( sentence.charAt(i) != ' ')
{
count = count + 1;
}
}
Also you might want to change the return type to an int instead of an Object.
The algorithm could be further improved, but to adress the asked qestion: You got the if..else.. wrong.
You should count up in the if and break out of the while loop in the else block:
if (sentence.charAt(i) != ' ')
{
count++;
i++;
}
else
{
break;
}
EDIT: As others have mentioned, there is a shorter way using indexOf (it returns the 0-based position of a character). You also get your solution with this code instead of the while block:
if (sentence.contains(" "))
{
count = sentence.indexOf(' ');
}
I think you wanted to get the number of characters before the first space.
If you want to make your code work, then you can use the following code:
public int firstBlankPosition(){
int i = 0;
while ( i < sentence.length()){
if(sentence.charAt(i) == ' '){
return i;
}
i++;
}
return i;
}
sentence.indexOf(' ') would work if there is a space in sentence. However, it would return -1 if there is no space in the input string.

get the last digit from the name

i want to know if i can get the last digit of the input, but if the last one is 0 i want it to ignore it and take the one before it... like bob120, last digit is 20 not 0, to make it the level for the person
here is my code and i tried for 2 days to know how but i'm stuck with this problem.
and i tried %10 but still it's the same problem.
number = number.substring(5,6);
level = Integer.parseInt(number);
I'm using scanner package
thank you in advance
if the input is a String and you like the use substring the code will be
int pos= number.lenght();
String lastChar = number.substring(pos-1,pos);
Note: number is a String : )...
Then you are right on the Integer.parseInt(), be aware of error if its not a number (try, catch)...
Then you need a if statement...change your pos and try again....
To do this task it would be better to use the String.toCharArray() at loop it backwards... so if you have time study this..
Something like this:
public int getLastNumDifThenZero(String text){
char[] ca = text.toCharArray();
for (int i = ca.length-1; i >= 0; i--) {
char a = ca[i];
try {
int n = Integer.parseInt(String.valueOf(a));
if (n!=0){
return n;
}
} catch (NumberFormatException e) {
//Not a number
}
}
return -1;
}
You can loop from the end of String and search for 'non-zero' value (result char is String) :
public static void main(String[] args) {
// example returns 7
String num = "85677000";
char lastDigit =' ';
// looping from end and searching non zero digit
for(int i=num.length()-1 ; i>=0 ;i--){
lastDigit=num.charAt(i);
if (lastDigit != '0'){
System.out.println(lastDigit);
break;
}
}
}

What am I doing Wrong here [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 8 years ago.
I made a program to search for a certain string in another string and print Word found if the condition is true or print word not found if condition is false
The logic is as follows
enter word
length of word
for searching for letter [1]
if true
then for till length of word match with string to be searched
else continue loop
But I always get word not found no matter what the input, please help me over here!!!
The code is as follows :-
import java.util.Scanner;
class Search_i_String
{
public static void main(String args[])
{
int flag=0;
Scanner Prakhar=new Scanner(System.in);
System.out.println("Enter a String");
String ori=Prakhar.nextLine();
System.out.println("Enter the String to be Searched");
String x=Prakhar.nextLine();
char a[]=new char[ori.length()];
char b[]=new char[x.length()];
for(int i=0;i<ori.length();i++)
{
a[i]=ori.charAt(i);
}
for(int i=0;i<x.length();i++)
{
b[i]=x.charAt(i);
}
for(int i=0;i<a.length;i++)
{
if (a[i]==b[0])
{
for(int j=0;j<b.length;j++)
{
while(flag==0)
{
if(b[j]==a[i])
{
flag=0;
}
else if(b[j] != a[i])
{
flag=1;
}
i++;
}
}
}
}
if (flag==0)
{
System.out.println("Word Found !!!");
}
else
System.out.println("Word not Found");
}
}
P.S. : I know I can use the contains() function but I can as my professor suggests against it and could someone please correct the program I have written, because I could have scavenged off a program from the internet too if I had to, I just wanted to use my own logic
Thank You(again)
while(flag==0)
{
if(b[j]==a[i])
{
flag=0;
}
else if(b[j] != a[i])
{
flag=1;
}
i++;
j++; //add this and try once
}
If you are comparing strings in Java, you have to use equals();
So, stringA.equals(stringB);
Cheers!
Let me get this straight. You're looking for b array inside of a array? "Enter the string to be searched" means that you are searching the other way around, but I'll go with the logic your code seems to follow... Here's a naive way to do it:
if (a[i]==b[0])
{
flag = 0;
for(int j=0;j<b.length;j++)
{
if(b[j] != a[i+j]) // will array index out of bounds when its not foud
{
flag++; // you should probably break out of a named loop here
}
}
if(flag == 0){/*win*/}
}
You're modifying your first search loop with variable i when you don't have to. You can just add i to j. Also, you don't need the while loop inside if i'm understanding your problem. Like others have said, functions exist to do this already. This algorithm isn't even as efficient as it could be.
I know of an algorithm where you check starting in the last character in b instead of the first character in b to begin with. Then you can use that information to move your search along faster. Without resorting to full pseudo code, anyone know what that's called?
The simple way(but not the fastest way) is use double loop to check the chars in strings one by one, pls ref to my code and comments:
public class SearchString {
public static void main(String[] args) {
String a = "1234567890";
String b = "456";
// Use toCharArray() instead of loop to get chars.
search(a.toCharArray(), b.toCharArray());
}
public static void search(char[] a, char[] b) {
if (a == null || b == null || a.length == 0 || b.length == 0) {
System.out.println("Error: Empty Input!");
return;
}
int lenA = a.length, lenB = b.length;
if (lenA < lenB) {
System.out
.println("Error: search key word is larger than source string!");
return;
}
// Begin to use double loop to search key word in source string
for (int i = 0; i < lenA; i++) {
if (lenA - i < lenB) { // If the remaining source string is shorter than key word.
// Means the key word is impossible to be found.
System.out.println("Not found!");
return;
}
// Check the char one by one.
for (int j = 0; j < lenB; j++) {
if (a[i + j] == b[j]) {
if (j == lenB - 1) { // If this char is the last one of key word, means it's found!
System.out.println("Found!");
return;
}
} else {
// If any char mismatch, then right shift 1 char in the source string and restart the search
break;
}
}
}
}
}
You can just use String.contains();
If you really want to implement a method, try this one:
public static void main(String[] args) {
// Initialize values searchedWord and original by user
String original = [get original word from user] ;
String searchedWord = [get searched for word from user];
boolean containsWord = false;
int comparePosition = 0;
for(int i = 0; i < original.length() - searchedWord.length(); i++) {
if(original.charAt(i) == searchedWord.charAt(comparePosition)) {
comparePosition += 1;
} else {
comparePosition = 0;
}
if(comparePosition == searchedWord.length()) {
containsWord = true;
break;
}
}
return containsWord? "Word found!!" : "Word not found.";
}

Deleting Duplicate Characters in a String

Hi I need to fix this code to delete characters that repeat immediately in the string. For example: If I type aaabbbcccdeeff, it has to return abcdef at the end. However on the computer in class it returns something of a, "out of range (number)", the number being dependent on how many characters I used. On my mac however it just returns a number like 3 as an output and gives no error message. I am on Eclipse.
Please help, I didn't understand what the professor said and he rarely helps. The code is (somewhat helped by professor):
package firstProgramSimple;
import java.awt.Toolkit;
import java.util.Scanner;
public class SimpleVersion {
public static void main(String[] args) {
Scanner kb = new Scanner(System. in );
System.out.println("Entre String");
String string = kb.nextLine();
//System.out.println(string);
int length = string.length();
for (int i = 1; i < length; i++) {
if (string.charAt(i) != string.charAt(i - 1)) {
System.out.print(i);
} else if (string.charAt(i) != string.charAt(i)) {
System.out.print(i);
}
}
}
}
You need to print string.charAt(i) and not i.
Also, this piece of code is unnecessary since it will always return false:
//string.charAt(i) is always equal to itself
else if ( string.charAt(i) != string.charAt( i )) {
System.out.print(i);
Since you start at i = 1, the char at index 0 will never be printed. Before the for-loop, you should add this line:
System.out.print(string.charAt(0));
You are printing your loop counter and not the value of the char at the position of the counter:
System.out.print(i);
Should be:
System.out.print(string.charAt(i));
You will get an arrayOutOfBoundsException for inputs of size < 2. You might want to add this line once you have the string initialised:
if(string == null || string.length() < 2){
System.out.println(string);
return;
}
Something like this:
public static void main(String[] args) {
Scanner kb = new Scanner(System. in );
System.out.println("Entre String");
String string = kb.nextLine();
//System.out.println(string);
int length = string.length();
if(length < 2) {
System.out.println(string);
return;
}
System.out.print(string.charAt(0));
for (int i = 1; i < length; i++) {
if (string.charAt(i) != string.charAt(i - 1)) {
System.out.print(string.charAt(i));
}
}
}
Just replace your for loop like bellow:
System.out.print(string.charAt(0));
for (int i = 1; i < length; i++) {
if (string.charAt(i) != string.charAt(i - 1)) {
System.out.print(string.charAt(i));
}
}
The idea is, print the beginning character first, then print the character at i th position, only if its different then its previous character. Simple!

Periodic Strings

I am trying to solve this String manipulation problem, where I need to find the smallest period of a given string.
A string is said to have period k if it can be formed by concatenating one or more repetitions of another string of length k.
For example, the string "abcabcabcabc" has period 3, since it is formed by 4 repetitions of the string "abc". It also has periods 6 (two repetitions of "abcabc") and 12 (one repetition of "abcabcabcabc"). Here's my code :
public static int getPeriod(String str){
int len=str.length();
boolean flag=false;
int i;
for (i=0;i<len;i++){
String s=str.substring(0,i);
String tmp=str;
while(tmp.length()>0){
if(tmp.startsWith(s)){
tmp=tmp.substring(0,i);
flag=true;
}
else {
flag=false;
continue;
}
}
if (flag==true)
break;
}
return i;
}
I am forming a string s by looping through the original string, one character at a time. After, that I am checking if the original string can be completely exhausted by concatenating the string s any number of times, or not.
ERROR:
The method always returns 0.
Why is that so ?
EDIT : My algorithm
Lets consider the input string HoHoHo
First step: s=H
tmp= HoHoHo
tmp= oHoHo (after substringing tmp)
'o' isn't the same as s, so we increase i
Second step:s=Ho
tmp= HoHoHo
tmp= HoHo (after substringing tmp)
tmp= Ho (after substringing tmp)
tmp= "" (after substringing tmp)
Return the value of i, that is 2.
The code inside the while loop isn't correct, it's called during the first invocation of the for loop with i=0 and hence the first assignment to the tmp variable sets it to the empty string, the loop exits and you get 0. The flag assignments and the continue in the else are not correct too.
Try this:
public static int getPeriod(String str) {
int len = str.length();
int i;
for (i = 1; i <= len/2; i++) {
String period = str.substring(0, i);
String tmp = str;
boolean flag = true;
while (flag && tmp.length() > 0) {
if (tmp.startsWith(period)) {
tmp = tmp.substring(i);
} else {
flag = false;
}
}
if (flag == true) {
return i;
}
}
return 0;
}
Notice that the for loop starts from 1 and goes to len/2 because you don't want to check for the zero length period and there can't be periods longer than n/2.
In the first loop iteration, i == 0, so s is "" (empty string), and tmp is also "" after the first iteration over while loop, so tmp also becomes "" and exits all the loops.
Starting with i = 0 will always return true because substring(0,0) will return the "" string and tmp.startsWith("") is always true.
First you should start i from 1, also you should replace continue with break, because continue will continue your while loop but what you want to do is continue the for loop and not the while loop
Here is a version of your code working:
public static int getPeriod(String str){
int len=str.length();
boolean flag=false;
int i;
for (i=1;i<len;i++){
String s=str.substring(0,i);
String tmp=str;
while(tmp.length()>0){
if(tmp.startsWith(s)){
tmp=tmp.substring(i);
flag=true;
}
else {
flag=false;
break;
// Replaced continue with break to exit the while loop and pass
// to the next value in the for loop
}
}
if (flag==true)
break;
}
return i;
}
I know this is an old question. The problem can be solved in linear time using Knuth's Prefix Function.
public static int prefixFunction(final String needle)
{
//This code does not include input validation. Validate the input and return appropriate error message
int[] pf = new int[needle.length()];
for (int i = 1; i < needle.length(); i++)
{
int j = pf[i - 1];
while (j > 0 && needle.charAt(i) != needle.charAt(j)) j--;
if (needle.charAt(i) == needle.charAt(j)) ++j;
pf[i] = j;
}
int n = needle.length(), maxValue = pf[n - 1];
if(maxValue == 0 || n%(n-maxValue) != 0) return -1; //Not periodic
return needle.length() - maxValue;
}

Categories

Resources