Queries on subsequence of string - java

Given a string S and Q queries, each query contains a string T. The task is print “Yes” if T is subsequence of S, else print “No”.
I am trying to learn algorithms and implementing them.
I have written the below code in Java :
import java.util.Stack;
public class QueriesOnStringSubsequence {
public boolean subSequence(String original, String query) {
Stack<Character> s1 = new Stack<Character>();
Stack<Character> s2 = new Stack<Character>();
for (int i = 0; i < original.length(); i++) {
s1.push(original.charAt(i));
System.out.println(s1.peek());
}
for (int i = 0; i < query.length(); i++) {
s2.push(query.charAt(i));
System.out.println(s2.peek());
}
while (!s1.isEmpty() || !s2.isEmpty()) {
Character s1Top = s1.peek();
Character s2Top = s2.peek();
if (s1Top == s2Top) {
s1.pop();
//System.out.println(i);
s2.pop();
return true;
}
System.out.print("True");
}
System.out.print("False");
return false;
}
public static void main(String[] args) {
QueriesOnStringSubsequence ob = new QueriesOnStringSubsequence();
ob.subSequence("geeksforgeeks", "gg");
}
}
I tried to debug this and in Eclipse and it won't go into the if condition. Can someone please explain where I am going wrong.

Keep in mind that Stack are LIFO data structures.
This means when you run:
Character s1Top = s1.peek();
Character s2Top = s2.peek();
You are getting the last two characters added. In this case s and g.
This means that the if statement will not be met. The second time the software loops since you are using Stack.peek the element is looked at but not changed. Therefore your while loop is looking at s and g over and over. Since they are never equal your if will never be met and therefore your while loop will be infinite.
Also you are checking:
while(!s1.isEmpty() || !s2.isEmpty())
This means both need to be empty before exiting which can cause an issue. I believe you want to use:
while(!s1.isEmpty() && !s2.isEmpty())

As duncan pointed out, a stack may not be the best data structure for this. I assume you want to go in order which means that you should use a queue.
Here is an implementation. I used better variable naming conventions which help not only in readability, but also debugging.
import java.util.*;
public class QueriesOnStringSubsequence {
public static void subSequence(String original, String query) {
Queue<Character> originalQueue = stringToQueue(original);
Queue<Character> queryQueue = stringToQueue(query);
while (!originalQueue.isEmpty() && !queryQueue.isEmpty()) {
Character originalQueueHead = originalQueue.peek();
Character queryQueueHead = queryQueue.peek();
if (originalQueueHead.equals(queryQueueHead)) {
queryQueue.poll();
System.out.print("YES");
} else {
System.out.print("NO");
}
originalQueue.poll();
System.out.print("...");
}
}
private static Queue<Character> stringToQueue(String input) {
Queue<Character> queue = new LinkedList<Character>();
for (int i = 0; i < input.length(); i++) {
queue.add(input.charAt(i));
}
return queue;
}
public static void main(String[] args) {
QueriesOnStringSubsequence.subSequence("geeksforgeeks", "gg");
}
}
YES...NO...NO...NO...NO...NO...NO...NO...YES...

Related

Java- function seems to mess up the console, nothing will be printed out after calling the function

I was asked to program a method that receives a scanner, and returns a sorted array of words which contain only letters, with no repetitions (and no bigger in length than 3000). Then, I was asked to program a method that checks whether a certain given string is contained in a given vocabulary. I used a simple binary search method.
This is what I've done:
public static String[] scanVocabulary(Scanner scanner){
String[] array= new String[3000];
int i=0;
String word;
while (scanner.hasNext() && i<3000) {
word=scanner.next();
if (word.matches("[a-zA-Z]+")){
array[i]=word.toLowerCase();
i++;
}
}int size=0;
while (size<3000 && array[size]!=null ) {
size++;
}
String[] words=Arrays.copyOf(array, size);
if (words.length==0 || words.length==1) {
return words;
}
else {
Arrays.sort(words);
int end= removeDuplicatesSortedArr(words);
return Arrays.copyOf(words, end);
}
}
private static int removeDuplicatesSortedArr(String[] array) { //must be a sorted array. returns size of the new array
int n= array.length;
int j=0;
for (int i=0; i<n-1; i++) {
if (!array[i].equals(array[i+1])) {
array[j++]=array[i];
}
}
array[j++]=array[n-1];
return j;
}
public static boolean isInVocabulary(String[] vocabulary, String word){
//binary search
int n=vocabulary.length;
int left= 0;
int right=n-1;
while (left<=right) {
int mid=(left+right)/2;
if (vocabulary[mid].equals(word)){
return true;
}
else if (vocabulary[mid].compareTo(word)>0) {
right=mid-1;
}else {
right=mid+1;
}
}
return false;
}
while trying the following code:
public static void main(String[] args) {
String vocabularyText = "I look at the floor and I see it needs sweeping while my guitar gently weeps";
Scanner vocabularyScanner = new Scanner(vocabularyText);
String[] vocabulary = scanVocabulary(vocabularyScanner);
System.out.println(Arrays.toString(vocabulary));
boolean t=isInVocabulary(vocabulary, "while");
System.out.println(t);
System.out.println("123");
}
I get nothing but-
[and, at, floor, gently, guitar, i, it, look, my, needs, see, sweeping, the, weeps, while]
nothing else is printed out nor returned. Both functions seem to be working fine separately, so I don't get what I'm doing wrong.
I would be very happy to hear your thoughts, thanks in advance :)
This has nothing to do with the console. Your isInVocabulary method is entering an infinite loop in this block:
if (!isInVocabulary(vocabulary, "while")) {
System.out.println("Error");
}
If you were to debug through isInVocabulary, you would see that after a few iterations of the while loop,
left = 0;
right = 2;
mid = 1;
if (vocabulary[mid].equals(word)){
// it doesn't
} else if (vocabulary[mid].compareTo("while") > 0) {
// it doesn't
} else {
right = mid + 1;
// this is the same as saying right = 1 + 1, i.e. 2
}
So you'll loop forever.

receive multiple char input from a single line in java

I am writing a stack data structure in java using arrays. The problem is when I try to push the users char input it doesn't display. The problem is with this code.
public static void preSuf(Stack stack) {
Scanner key = new Scanner(System.in);
System.out.println("enter the values");
while(key.hasNext()){
char c = key.next().charAt(0);
stack.push(c);
}
}
When I change the while(key.hasNext()) to if(key.hasNext()) it works but it only prints one time and doesnt itterate. How can I fix this problem thank you.
Edit: Here is the whole code
import java.util.Scanner;
public class Stack {
private int top;
private char[] container;
private int size;
public static int pos = 0;
// constructor
public Stack(int N) {
container = new char[N];
size = N;
top = 0;
}
public boolean isFull() {
return (size == top);
}
public void push(char string) {
if (!isFull()) {
container[top] = string;
top++;
} else {
return;
}
}
public int pop() {
int drop;
drop = container[top - 1];
container[top] = 0;
top--;
return drop;
}
public int peek() {
int drop2;
drop2 = container[top - 1];
return drop2;
}
public void display() {
for (int i = 0; i < container.length; i++) {
if (container[i] != 0) {
System.out.print(container[i]);
}
}
}
public static void preSuf(Stack stack) {
Scanner key = new Scanner(System.in);
System.out.println("enter the values");
while(key.hasNext()){
char c = key.next().charAt(0);
stack.push(c);
}
}
public static void main(String args[]) {
Stack stack = new Stack(3);
preSuf(stack);
stack.display();
stack.display();
System.out.println();
}
}
The problem is that you haven't written any code to actually print the contents of your stack.
You could write a loop after your while loop to iterate over the stack and print out each character.
You'll also need a way of exiting your while loop. You can do this either with a special character, eg. if(c == '.') break; or you can just press Ctrl+Z.
EDIT: Based on the edit to the question and the full code being presented, I think the suggestion of needing the extra loop is now redundant. You have that in stack.display(). You just need to get out of your while loop.
you haven't determined when the loop should end.
you'd think if you press enter without entering anything the loop
would break but that's not how next operates. if you press enter
without entering anything or input data which consists of only whitespaces, next will block while waiting for input to
scan, even if a previous invocation of hasNext() returned true.
the solution is to include a condition at which control should break out of the loop.

Java Arrays[] - Assigning Specific Elements in a For Loop to Certain Values

I was attempting to write some code for a program in BlueJ (Java) that lists bags and adds and removes items from those bags, that sort of thing. Then I got stuck in the first class; I couldn't get to add an item to the bag properly as you can notice below in the addItem() method; it keeps adding String s to every null element in the array rather the first encountered. Any help would be tremendously appreciated.
Best wishes & many thanks,
Xenos
public class Bag1 {
private String[] store; // This is an array holding mutlitple strings.
public Bag1(int storageCapacity) {
store = new String[storageCapacity];
} // That was the primitive array constructor.
public boolean isFull() {
boolean full = true;
for(int i = 0; i < store.length; i++) {
if(store[i] == null) {
full = false;
}
}
return full;
} // The method above checks if the bag is full or not, and returns a boolean value on that basis.
public void add(String s) {
for(int i = store.length; i >= 0; i--) {
if(store[i] == null) {
store[i] = s;
}
}
}
}
You should exit the loop after finding the first empty spot :
public void add(String s)
{
for(int i=store.length-1; i>=0; i--) { // note the change in the starting index
if(store[i]==null) {
store[i] = s;
break;
}
}
}

For loop input in BlueJ (infinite loop)

I'm working on a project for school and am stumped at where I am at the moment. When I run my project, the VM seems to be stuck in a loop and will not load (A console should pop up allowing me to input characters for the CombinationLock class setDigit() method). I believe it has something to do with my for loop in my Interface.java class. If anyone could take a look and lead me in the right direction, that'd be much appreciated. Thanks a bunch!
Interface.java
import java.util.*;
public class Interface
{
public static void main() {
Scanner in = new Scanner(System.in);
CombinationLock combo = new CombinationLock();
for(int i = 0; i < 3; i++) {
String ltr = in.nextLine();
combo.setDigit(ltr.charAt(0), i);
System.out.println("Digit " + i + " has been set to " + ltr);
}
}
}
CombinationLock.java
public class CombinationLock
{
String[] combo = new String[3];
public CombinationLock() { }
public boolean setDigit(char letter, int index) {
if (Character.isDigit(letter)) {
return false;
}
combo[index] = String.valueOf(letter);
return true;
}
public boolean unlock(String combo) {
if (combo.length() > 3) {
return false; //Longer then it can be, not valid
}
char[] comboArray = combo.toCharArray();
for (char c : comboArray) {
if (Character.isDigit(c)) {
return false; //Contains numbers, not valid
}
}
boolean valid = true;
for (int i = 0; i < 3; i++) {
if (combo.charAt(i) != comboArray[i] && valid == true) {
valid = false;
break;
}
}
return valid;
}
}
You have initialized combo array in CombinationLock class with length 0 as String[] combo = {};. This is cause ArrayIndexOutOfBoundsException when you are calling combo.setDigit(ltr.charAt(0), i);. Please correct the initialization. I beleive you want to capture 3 inputs, in that case, please initialize combo in CombinationLock with length 3 as below:
String[] combo = new String[3];
Your problem is (the signature of the main method is wrong)
public static void main() {
it should be
public static void main(String[] args) {
I've found where my error was, using the BlueJ IDE one must output something to the console before it shows up and allows you to input data, therefore it never popped up as I never used System.out.println or System.out.print. After doing so, the console popped up and allowed me to input my data. Thanks you for all your suggestions and help!

Simple method query

I have the following code which returns an error.
The line:
return first;
says:
incompatible types, required: char[]
It seems like something simple, but I can't figure it out. I am trying to display the values from invoking methodB.
Also, you will notice I have commented an if statement as #4. Can someone further my understanding a bit.
Does this if statement update the value held by the variable first IF the value held in the current element in alphas comes before the current value of first?
Hope this makes sense and someone can help. Getting late and my brain isn't working any more. Java is going to make or break me!
package openuniversity;
public class Main
{
public static void main(String[] args)
{
Main m = new Main();
char [] alp = m.methodB();
for (char b: alp)
{
System.out.println(b);
}
}
public static char[] methodB()
{
char [] alphas = {'s','a','u','s','a','g','e'};
char first = alphas[0];
for (int i= 1; i < alphas.length; i++) //3
{
if (alphas[i] < first) //4
{
first = alphas[i];
}
}
return first;
}
}
package openuniversity;
public class Main
{
public static void main(String[] args)
{
Main m = new Main();
char alp = m.methodB();
System.out.println(alp);
}
public static char methodB()
{
char [] alphas = {'s','a','u','s','a','g','e'};
char first = alphas[0];
for (int i= 1; i < alphas.length; i++) //3
{
if (alphas[i] < first) //4
{
first = alphas[i];
}
}
return first;
}
}
Your function signature says you're returning a char[]:
public static char[] methodB()
But you actually return a char:
char first = alphas[0];
// ...
return first;
It's not entirely clear what you want to do, but you need to either change the signature to return a single char:
public static char methodB()
And change where it's used:
char alp = m.methodB();
Or make methodB actually return a char[]. The problem is I don't know what it's actually supposed to return. I'd suggest giving the function a better name. You may want to take a look at Lists.

Categories