Stuck in a loop when there is no matching - Java - java

So here I am stuck with my program where its a simple thing to do. so basically in the search metod is where I have 3 variables as you can see, Char P char T and List pos. Below the method you can see there is a Main where its says what value the char P, char T has and my idea was to make a matching program where I enter a value P and looks if there is a same value in char T. Ones it founds out, it should continue until the value is done. so in the main method after it found out the result, it should give you the index of what position the value is set to.
Now to the problem is, if I give a correct value example P =abc T = abcqweqweabc it would give me a correct, but if I do abcqweqweqwe it will loop all the time and never end which is killing my processor and ram (hehe) and I have been trying to figure out but I can't find the problem. It seems like it should work and I don't understand why it does like it.
public class StringSearch {
public static void search(char[] P, char[] T, List<Integer> pos) {
int i = 0;
int j;
while(i!=P.length){
for (j= 0; j<T.length; j++){
if(P[i] == T[j]) {
i++;
if(i == P.length) {
pos.add((j-(P.length-1)));
i = 0;
if(j==T.length-1) {
i = P.length;
}
}
}
else {
i = 0;
}
}
}
public static void main(String[] args) {
ArrayList<Integer> where = new ArrayList<Integer>();
search("abcx".toCharArray(), "abcdabcxxabctx".toCharArray(), where);
for (int i : where) {
System.out.println(i);
}
}
}
Also please! If you need to know something. Just comment and I will probably answer you in a minute! Feel free to ask question aswell!
EDIT: To give a exactly meaning of what I'm trying to do is that, Our Char T is where the "text" is and char P is where letters are that I want to match P and T. So whenever we find a correct matching between char P and T it should be add in the list which we called pos. which will give us later a result where in the index the matching is the same. like T = qweabcqwe and P = abc. It should give us a result of 4. so what I'm trying to do is to see if there is a matching between those two and where in the position are they the same and if there is, put in the list and then the loop at the main method will tell us where.
EDIT PART 2.3:
public static void search(char[] P, char[] T, List<Integer> pos) {
for (int i=0;i<=T.length-P.length;) {
if (T[i] == P[0]) {
boolean match=true;
for (int j=0;j<P.length;j++) {
if (T[i+j] != P[j]) {
match = false;
break;
}
}
if (match) {
pos.add(i);
i = P.length -1;
}
}
}
}
public static void main(String[] args) {
ArrayList<Integer> where = new ArrayList<Integer>();
search("abcx".toCharArray(), "abcdabcxxabctx".toCharArray(), where);
for (int i : where) {
System.out.println(i);
}
}
}

if there is even one case where
if(P[i] != T[j])
then you set i to 0
else {
i = 0;
and you get stuck in the while loop
BUT basicaly what you are trying to do is something that gives you the same result as indexOf()
Try this :
String Str = new String("qweabcqwe");
String SubStr1 = new String("abc");
System.out.println( Str.indexOf( SubStr1 )); // will print 3

You might want to check out the KMP algorithm explaind in detail using Java here to give you some hints if you want to implement it yourself: http://tekmarathon.com/2013/05/14/algorithm-to-find-substring-in-a-string-kmp-algorithm/

To find the index of every character that is the same at the same position in each array just do:
for (int i=0;i<P.length && i<T.length;i++) {
if (P[i] == T[i]) {
pos.add(i);
}
}
You only need one loop as you are only comparing one value.
If you want to find the location of the substring then you do need a nested loop but it can still be a simple for loop.
for (int i=0;i<=P.length-T.length;i++) { // Can stop when we get to within T length of the end of P
if (P[i] == T[0]) {
boolean match=true;
for (j=0;j<T.length;j++) {
if (P[i+j] != T[j]) {
match = false;
break;
}
}
if (match) {
pos.add(i);
// You might want to add T.length-1 to i here to cause it to skip, it depends if you want to find overlapping results or not. (i.e. searching for bobob in bobobob.
}
}
}

Related

Writing a Recursive Function in Java to output a set of words in all combinations

I would like to see how to get the following output by using a Java recursive function. Would be great to get some insight on how to go about solving a problem like this. The recursive Java function should take these words: "MIKE", "AND", "IKE" and output each ordering on a separate line such as this.
MIKEANDIKE
MIKEIKEAND
IKEANDMIKE
IKEMIKEAND
ANDIKEMIKE
ANDMIKEIKE
public static void main(String[] args) {
recur(new String[]{"MIKE", "AND", "IKE"}, "", 0);
}
public static void recur(String[] words, String result, int n) {
if (n == words.length) {
System.out.println(result);
return;
}
for (int i = 0; i < words.length; ++i) {
String out = result + words[i];
recur(words, out, n + 1);
}
}
You need to flag in some way the values that you have already used, in this example I use the null for that purpose, but there are other approaches to it (for example using a list and deleting/adding the values, or duplicating the lists themselves).
public static void recur(String[] words, String result, int n) {
if (n == words.length) {
System.out.println(result);
return;
}
String temp;
for (int i = 0; i < words.length; ++i) {
if (null != words[i]) {
String out = result + words[i];
temp = words[i];
words[i] = null;
recur(words, out, n + 1);
words[i] = temp;
}
}
}
The main thing to keep in mind is that you need to keep a state variable to decide the combination to print in each recursive call.
For example, the state variable could be a 3 digit number i.e. 123. And then map these digits with the words, for example, 1 is "MIKE", 2 is "AND", 3 is "IKE". So if the function is called with 123 then you would print "MIKEANDIKE", and then call again with next permutation of 123 which is 132 and so on.
I just mentioned one possible state variable variation. There could be countless way to declare a state variable. The main idea you can get from this is an idea of how you can approach to solve the problem.
Hope this helps! Let me know if don't understand anything. Happy coding!

Print out strings from an arraylist in a given range java?

My method is supposed to print out all of the strings in between 2 strings in my ArrayList, exclusive of both the beginning string and the end string.
public void printRange(String beg, String end)
{
for(int i = 0; i < list.size(); i++)
{
}
}
String beg is the beginning string and String end is the last string. To further clear up, if I have an ArrayList containing the words "dog" "cat" "apple" "banana" "turtle", and I enter in "cat" and "turtle", the method should print out "apple" and "banana".
I know I should iterate through the list, but I'm lost as to where I go from there.
Edit: Sorry for posting 2 questions! I'll submit them differently next time.
Try using a flag to avoid one more N iteration.
public void printRange(String beg, String end)
{
boolean startPrinting = false;
for (int i = 0; i < list.size(); i++)
{
if (startPrinting) {
System.out.println(list.get(i));
}
if (list.get(i).equals(beg)) {
startPrinting = true;
} else if (list.get(i).equals(end)) {
break;
}
}
}
I would edit out the second question. You don't post two questions for one topic on SO.
Regarding your first question, you want to get the index of where the first string and the last string are found. Something like this:
public void printRange(String beg, String end)
{
int begIdx, endIdx;
for(int i = 0; i < list.size(); i++)
{
if (list[i].equals(beg)) {
begIdx = i;
}
if (list[i].equals(end)) {
endIdx = i;
}
}
for(int i = begIdx; i < endIdx; i++)
// Print range...
}
That's a quick and dirty implementation. You can do this in one traversal of the list.
You can also make use of the indexOf() method. I am not sure what you are up to, but bear in mind a List can contain duplicate keys. Consider using a Set instead.
package com.company;
import java.util.ArrayList;
import java.util.List;
public class Main {
private List<String> list = new ArrayList<String>();
{
list.add("dog");
list.add("cat");
list.add("apple");
list.add("banana");
list.add("turtle");
}
public void printRange(String beg, String end)
{
int start = list.indexOf(beg) + 1;
int finish = list.indexOf(end);
if (start <= 0 || start >= finish) return;
for(int i = start; i < finish; i++)
{
System.out.println(list.get(i));
}
}
public static void main(String[] args) {
new Main().printRange("cat", "turtle");
}
}
I'd use a tiny state machine -
state 0 = beginning not found
state 1 = beginning found, end not found
state 2 = end found (or could go back to 0 if you want to look for beginning again)
You need relevant checks to change the state and only have to print stuff out when you're in state 1.
This way you only have to go through the list once instead of going through it (partially) to find beginning and end, and then going through it (partially) again to output required fields.

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

Count Occurence of Needle String in Haystack String, most optimally?

The Problem is simple Find "ABC" in "ABCDSGDABCSAGAABCCCCAAABAABC" without using String.split("ABC")
Here is the solution I propose, I'm looking for any solutions that might be better than this one.
public static void main(String[] args) {
String haystack = "ABCDSGDABCSAGAABCCCCAAABAABC";
String needle = "ABC";
char [] needl = needle.toCharArray();
int needleLen = needle.length();
int found=0;
char hay[] = haystack.toCharArray();
int index =0;
int chMatched =0;
for (int i=0; i<hay.length; i++){
if (index >= needleLen || chMatched==0)
index=0;
System.out.print("\nchar-->"+hay[i] + ", with->"+needl[index]);
if(hay[i] == needl[index]){
chMatched++;
System.out.println(", matched");
}else {
chMatched=0;
index=0;
if(hay[i] == needl[index]){
chMatched++;
System.out.print("\nchar->"+hay[i] + ", with->"+needl[index]);
System.out.print(", matched");
}else
continue;
}
if(chMatched == needleLen){
found++;
System.out.println("found. Total ->"+found);
}
index++;
}
System.out.println("Result Found-->"+found);
}
It took me a while creating this one. Can someone suggest a better solution (if any)
P.S. Drop the sysouts if they look messy to you.
How about:
boolean found = haystack.indexOf("ABC") >= 0;
**Edit - The question asks for number of occurences, so here's a modified version of the above:
public static void main(String[] args)
{
String needle = "ABC";
String haystack = "ABCDSGDABCSAGAABCCCCAAABAABC";
int numberOfOccurences = 0;
int index = haystack.indexOf(needle);
while (index != -1)
{
numberOfOccurences++;
haystack = haystack.substring(index+needle.length());
index = haystack.indexOf(needle);
}
System.out.println("" + numberOfOccurences);
}
If you're looking for an algorithm, google for "Boyer-Moore". You can do this in sub-linear time.
edit to clarify and hopefully make all the purists happy: the time bound on Boyer-Moore is, formally speaking, linear. However the effective performance is often such that you do many fewer comparisons than you would with a simpler approach, and in particular you can often skip through the "haystack" string without having to check each character.
You say your challenge is to find ABC within a string. If all you need is to know if ABC exists within the string, a simple indexOf() test will suffice.
If you need to know the number of occurrences, as your posted code tries to find, a simple approach would be to use a regex:
public static int countOccurrences(string haystack, string regexToFind) {
Pattern p = Pattern.compile(regexToFind);
Matcher m = p.matcher(haystack); // get a matcher object
int count = 0;
while(m.find()) {
count++;
}
return count;
}
Have a look at http://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm
public class NeedleCount
{
public static void main(String[] args)
{
String s="AVBVDABCHJHDFABCJKHKHF",ned="ABC";
int nedIndex=-1,count=0,totalNed=0;
for(int i=0;i<s.length();i++)
{
if(i>ned.length()-1)
nedIndex++;
else
nedIndex=i;
if(s.charAt(i)==ned.charAt(nedIndex))
count++;
else
{
nedIndex=0;
count=0;
if(s.charAt(i)==ned.charAt(nedIndex))
count++;
else
nedIndex=-1;
}
if(count==ned.length())
{
nedIndex=-1;
count=0;
totalNed++;
System.out.println(totalNed+" needle found at index="+(i-(ned.length()-1)));
}
}
System.out.print("Total Ned="+totalNed);
}
}
Asked by others, better in what sense? A regexp based solution will be the most concise and readable (:-) ). Boyer-Moore (http://en.wikipedia.org/wiki/Boyer–Moore_string_search_algorithm) will be the most efficient in terms of time (O(N)).
If you don't mind implementing a new datastructure as replacement for strings, have a look at Tries: http://c2.com/cgi/wiki?StringTrie or http://en.wikipedia.org/wiki/Trie
If you don't look for a regular expression but an exact match they should provide the fastest solution (proportional to length of search string).
public class FindNeedleInHaystack {
String hayStack="ASDVKDBGKBCDGFLBJADLBCNFVKVBCDXKBXCVJXBCVKFALDKBJAFFXBCD";
String needle="BCD";
boolean flag=false;
public void findNeedle() {
//Below for loop iterates the string by each character till reaches max length
for(int i=0;i<hayStack.length();i++) {
//When i=n (0,1,2... ) then we are at nth character of hayStack. Let's start comparing nth char of hayStach with first char of needle
if(hayStack.charAt(i)==needle.charAt(0)) {
//if condition return true, we reach forloop which iterates needle by lenghth.
//Now needle(BCD) first char is 'B' and nth char of hayStack is 'B'. Then let's compare remaining characters of needle with haystack using below loop.
for(int j=0;j<needle.length();j++) {
//for example at i=9 is 'B', i+j is i+0,i+1,i+2...
//if condition return true, loop continues or else it will break and goes to i+1
if(hayStack.charAt(i+j)==needle.charAt(j)) {
flag=true;
} else {
flag=false;
break;
}
}
if(flag) {
System.out.print(i+" ");
}
}
}
}
}
Below code will perform exactly O(n) complexity because we are looping n chars of haystack. If you want to capture start and end index's of needle uncomment below commented code. Solution is around playing with characters and no Java String functions (Pattern matching, IndexOf, substring etc.,) are used as they may bring extra space/time complexity
char[] needleArray = needle.toCharArray();
char[] hayStackArray = hayStack.toCharArray();
//java.util.LinkedList<Pair<Integer,Integer>> indexList = new LinkedList<>();
int head;
int tail = 0;
int needleCount = 0;
while(tail<hayStackArray.length){
head = tail;
boolean proceed = false;
for(int j=0;j<needleArray.length;j++){
if(head+j<hayStackArray.length && hayStackArray[head+j]==needleArray[j]){
tail = head+j;
proceed = true;
}else{
proceed = false;
break;
}
}
if(proceed){
// indexList.add(new Pair<>(head,tail));
needleCount++;
}
++tail;
}
System.out.println(needleCount);
//System.out.println(indexList);

Checking if one array is the reverse of another array in java

Im trying to create a method that take 2 int array as the input parameter and returns true if the array are reverse and false otherwise. This is what I have so far but it is wrong.
public static void main(String[] args)
{
int b,a;
int[] data1 = {14,-70,-18,88,85,97,-65,13,-71,-12};
int[] data2 = {-12,-71,13,-65,97,85,88,-18,-70,14};
boolean check = true;
for (a=0;a<data1.length;a++)
{
for (b=data2.length-1;b>=0;b=b-1)
{
if (data1[a] != data2[b])
check=false
}
}
System.out.println(check);
}
My example is suppose to print true but it doesn't.I am assuming the 2 arrays are of the same length. Can anyone help?
You don't need two loops - you only need to loop once, using the index "normally" in one array, and from the other end for the other array:
public static boolean checkReversed(int[] x, int[] y)
{
// For production code, possibly add nullity checks here (see comments)
if (x.length != y.length)
{
return false;
}
// Loop through x forwards and y backwards
for (int i = 0; i < x.length; i++)
{
if (x[i] != y[y.length - 1 - i])
{
// As soon as we've found a "mistake" we can exit:
// This is simpler (IMO) than keeping a "check" variable
return false;
}
}
return true;
}
You can try doing:
// compare the length.
check = (data1.length != data2.length)?false:true;
// if lengths are equal..go ahead and compare elements in reverse.
if(check) {
for(int i=0,j=data2.length;(i<data1.length) && (j>=0);i++,j--) {
// if you find a mismatch..set check to false..and break
// no need to compare other ele.
if(data1[i] != data2[j]) {
check = false;
break;
}
}
}
in this, both array length should be equal. then
for(int i=0,j=array.length;i<array.length,j=0;i++,j--){
write your comparison logic here
}
Your code actually compares every element in data1 with every element with data2 and prints false if there is any one mismatch. That is not what you intend it to do.
here is an answer to your question in a complete .java file
//yeah.java
public class yeah {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] data1 = {14,-70,-18,88,85,97,-65,13,-71,-12};
int[] data2 = {-12,-71,13,-65,97,85,88,-18,-70,12};
System.out.println(isReverse(data1, data2));
}
public static boolean isReverse(int[] a, int[] b)
{
if (a.length != b.length) //If a and b are not of the same length how can they be reverse?
return false;
for (int i=0;i<a.length;i++)
if (a[i] != b[a.length-i-1])
return false;
return true;
}
}
Just a quick note about method and functions.. As soon as you discover that they are not reversed, you should exit using a return statement.. no need to keep on computing..
You can do it in one loop, you don't need two.
for (int i=0,j=end;i<end;i++,j--)
This can be done in a single loop there is no need for two loops.
For example:
for (int i = 0, j = last; i < last; i++, j--)

Categories

Resources