Reversing a String using a LinkedList based Stack [closed] - java

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
The assignment given to me is this: Create an application to reverse a list by using a linked list based Stack data structure. When you run the program, it asks you to type in an input. When you press Enter, it displays the input in reverse order. You decide the input data type this time.
I made my Node class or Link class, my LinkedList class, LinkedListStack Class, and now i am stuck in the main method.I posted all of my code below in hopes of someone helping me find the error I am making. I looked at other posts but most of them deal with either just reversing a linked list alone, a string, or a linkedlist arraylist.
This is the error I keep getting:
Please enter a word: Hello
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: -1
at java.lang.String.substring(String.java:1967)
at LinkedStackDemo.main(LinkedStackDemo.java:32)
public class Node
{
public String data;
public Node next;
public Node(String d)
{
data = d;
}
public void displayNode()
{
System.out.println(data + " ");
}
}
Linked List Class
public class LinkedList
{
public Node first;
public LinkedList()
{
first = null;
}
public boolean isEmpty()
{
return (first == null);
}
public void insertFirst(String d)
{
Node n = new Node(d);
n.next = first;
first = n;
}
public String deleteFirst()
{
//if(first == null)
//{return first;}
Node temp = first;
first = first.next;
//temp.next = null;
//return temp;
return temp.data;
}
public void displayNode()
{
Node current = first;
while(current != null)
{
current.displayNode();
current = current.next;
}
System.out.println(" ");
}
}
Linked Stack Class
public class LinkedListStack
{
private LinkedList node;
public LinkedListStack()
{
node = new LinkedList();
}
public boolean isEmpty()
{
return node.first == null;
}
public void push(String data)
{
node.insertFirst(data);
}
public String pop()
{
return node.deleteFirst();
}
public void displayStack()
{
System.out.println("Reversed order: ");
node.displayNode();
}
}
My main method (this is where i am getting very stuck)
import java.util.Scanner;
import java.util.Stack;
public class LinkedStackDemo
{
public static void main(String []args)
{
LinkedListStack s = new LinkedListStack();
LinkedList s1 = new LinkedList();
String input;
Scanner scan = new Scanner(System.in);
System.out.print("Please enter a word: ");
input = scan.nextLine();
s.push(input);
//String reverse = new StringBuffer(s.push(input)).reverse().toString();
//System.out.println(reverse);
for (int i = 1; i <= input.length(); i++)
{
while(i<=input.length())
{
String c = input.substring(i,i-1);
s.push(c);
}
//System.out.println("The stack is:\n"+ s);
s.displayStack();
}
}
}
I fixed the most recent problem but now it prints the code vertically instead of horizontally, this was my most recent problem.
This how it prints it out, the desired output would be to print the reverse like this, " olleH "Please enter a word: Hello Reversed order: H Hello Reversed order: e H Hello Reversed order: l e H Hello Reversed order: l l e H Hello Reversed order: o l l e H Hello
Taking out the System.out.println(" "); from displayNode; did not fix the problem for it printing out vertically.

The vast majority of the code here is totally irrelevant to the problem you describe. The only relevant bit is this:
for (int i = 1; i <= input.length(); i++)
{
while(i<=input.length())
{
String c = input.substring(i,i-1);
s.push(c);
}
//System.out.println("The stack is:\n"+ s);
s.displayStack();
}
The actual problem that you're seeing is the exception caused by passing in i and i-1 to String.substring. As it says in the Javadoc (emphasis mine):
[Throws] IndexOutOfBoundsException - if the beginIndex is negative, or endIndex is larger than the length of this String object, or beginIndex is larger than endIndex.
So, you need to call something else, like input.substring(i-1, i).
But there's another problem here: your while loop will never terminate, because i and input never change, so i<=input.length() never changes. As such, you'd just keep on pushing c into the stack until you run out of memory.
This while loop is simply unnecessary; remove it.

Related

How to print stack in reverse?

Stack <String> stackx = new Stack<String>();
Scanner word = new Scanner(System.in);
Scanner countz = new Countz(System.in);
System.out.println("How many time you want to input");
int repeat=countz.nextInt();
for (int i=0;i<repeat;i++){
System.out.println("Data of - "+ (i+1) + ":");
String pintri = word.nextLine();
stackz.push(pintri);
}
System.out.println("Your data: "+stackx);
I want to print the stackx in reverse order, how to do that?
Thank you..
You can print the reversed stack recursively:
void printReversed(Stack<?> stack) {
if (stack.isEmpty()) return;
Object value = stack.pop();
printReversed(stack);
System.out.println(value);
stack.push(value); // restore the stack.
}
This is, of course, working by pushing values into another stack - the call stack.
You use the pop() function to start removing the elements one by one. Stack removes element in LIFO (Last in First out), so naturally the elements will be removed (and accessed by the code) in the reverse order.
If you do not care about performance, you could reverse your Stack, print it, then reverse it back.
Collections.reverse(stackx);
System.out.println("Your data: " + stackx);
Collections.reverse(stackx);
On the other hand, if performance is important, you could use a StringBuilder to print the contents of the Stack data like this
StringBuilder stringBuilder = new StringBuilder();
for (String entry : stackx) {
stringBuilder.insert(0, entry + ", ");
}
stringBuilder.insert(0, "[").replace(stringBuilder.length() - 2, stringBuilder.length() - 1, "]");
If you want to reverse a stack,
Create a new temporary stack
You can use a while loop to pop the top element from stackx and push them onto the temporary stack till stackx becomes empty
Print this temporary stack. It will contain the reversed elements.
Stack<String> reversedStack = new Stack<>();
while(stackx.size() > 0) {
reversedStack(stackx.pop());
}
System.out.println("reversed elements: " + reversedStack);
The input and output are as below:
Input: How many time you want to input
3
Data of - 1:
hello
Data of - 2:
world
Data of - 3:
welcome
Your data: [hello, world, welcome]
reversed elements: [welcome, world, hello]
Just like you do with a list. Just iterate starting with the last index to the first.
for (int i = stackx.size()-1; i>=0; i--) {
System.out.println(stackx.get(i));
}
Using 2 Stacks
Psedudo-code
FirstStack <- add elements (push)
//Before print
SecondStack <- add FirstStack
(while FirstStack is not empty pop element form FirstStack and push into SecondStack
//both Stack's have the same elements but is reverse order
//print from SecondStack
(while SecondStack is not empty pop element and write on screen)
Also for learning purpose you could consider doing your own stack. Algorithm is the same no matter from where is taken the stack implementation.
import java.util.Stack;
public class TestNode {
public static void main(String[] args)
{
TestNode t = new TestNode();
//initial stack
Stack<String> s = new Stack<String>();
s.push("a");
s.push("b");
s.push("c");
//initial stack - same results
//Node s = t.new Node();
//s.push("a");
//s.push("b");
//s.push("c");
//intermediary stack
Node n=t.new Node();
while(!s.empty())
{
n.push(s.pop());
}
n.print();
}
//custom made stack based on linked-nodes
class Node
{
Node n=null;
String data=null;
Node()
{
}
Node(String data, Node n)
{
this.data = data;
this.n = n;
}
public void push(String data)
{
n = new Node(data,n);
}
public boolean empty()
{
if(data==null)
return true;
return false;
}
public String pop()
{
String out = data;
if(out != null)
{
n.data = null;
if(n.n != null)
{
n = n.n;
}
return out;
}
return null;
}
public void print()
{
Node cn = n;
while(cn != null)
{
System.out.println(cn.data);
cn = cn.n;
}
}
}
}
Output
a
b
c

Java Algorithms ResizingStringArrayQueue Resize Method Problems

So I'm in the process of learning how to use algorithms and I'm using the Algorithms Book By Robert Sedgewick to learn how to do this and the question is Exercise 1.3.14 (I would recommend highly if you are wanting to learn this stuff.) Anyway, I'm trying to implement my own resizing algorithm for my ResizingStringArrayQueue and I'm really struggling to get my implementation to work. But before I delve further into this, I would like to ask politely that I am NOT looking for a full solution to my resizing array (I'm trying to learn so need to do this by myself.) However if someone would be able to explain to me why my resizing method is failing to copy itself into a new larger array any help that can be offered would be greatly appreciated.
I would like to emphasise here that I'm focusing on the enque method, and am not working on the deque at this stage so please, no solution to how the deque works, thanks!
So here goes...
This is my implementation for the ResizingStringArrayQueue:
import java.util.Iterator;
public class ResizingArrayQueueOfStrings implements Iterable<String> {
private String[] a = new String[1];
private int n;
private int head;
private int tail;
public boolean isEmpty() { return n==0; }
public int size() {return n; }
public void aPrint() { // temporary method for testing needs deleting
System.out.println("Contents of array: ");
for (int i = 0; i < a.length; i++) {
System.out.print(a[i]+ " ");
}
}
private void resize(int max) {
String[] temp = new String[max];
for (int i = head; i < tail; i++) {
temp[i] = a[i];
a = temp;
}
}
public void enque(String item) { // something is in the wrong order here
if (tail == a.length) {
System.out.println("Capacity Doubled");
resize(2*a.length);
}
n++;
a[tail++] = item;
}
public String deque() {
if (head == tail/2) {
resize(n);
head = 0;
tail = n;
}
n--;
String item = a[head];
a[head++] = null; // loitering
return item;
}
public Iterator<String> iterator(){
return new ResizingArrayQueueIterator();
}
private class ResizingArrayQueueIterator implements Iterator<String>{
private int i = head;
#Override
public boolean hasNext() {
return i < tail;
}
#Override
public String next() {
// TODO Auto-generated method stub
return a[i++];
}
}
}
And this is a copy of my Main():
public static void main(String[] args) {
// TODO Auto-generated method stub
// EXERCISE 1.3.14
System.out.println("EXERCISE 1.3.14 ");
System.out.println();
ResizingArrayQueueOfStrings queueOfStrings = new ResizingArrayQueueOfStrings();
queueOfStrings.enque("a");
queueOfStrings.enque("b");
queueOfStrings.enque("c");
queueOfStrings.enque("d");
queueOfStrings.enque("e");
System.out.println();
for (String string : queueOfStrings) {
System.out.println(string);
}
System.out.println();
queueOfStrings.aPrint();
}
If you comment out the "enques" for c, d and e the code does what it should if you run it, I get a full queue [a,b]. However, when I get to c, my queue becomes [a,null,c, null] when it should be [a,b,c,null] for some reason it fails to copy the b. So I think the problem lies in the order I'm doing things and its somewhere most likely in the resizing method. I've spent a long time looking at this now and I'm getting to the stage where a second set of eyes would be really helpful. Thank you for your time and patience in advance, I look forward to hearing from you!
In resize, move the statement a = temp out of the for loop.

How do you print a stack in Java? [duplicate]

This question already has answers here:
How do I print my Java object without getting "SomeType#2f92e0f4"?
(13 answers)
Closed 4 years ago.
I have tried many different things to try to print this stack but it keeps printing the hashcode ie. Problem1$Node#3d4eac69. I have searched a lot online and found nothing that has worked for this so if there are any suggestions help is greatly appreciated.
import java.util.*;
public class Problem1 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
// Reading the first integer containing the number of test queries
int N = input.nextInt();
// Initializing the maximum value
int max = Integer.MIN_VALUE;
// Initializing the stack.
Stack<Node> stack = new Stack<Node>();
// Read the query and perform the actions specified.
for(int i = 0; i < N; i++){
int x = input.nextInt();
if(x == 1){
int value = input.nextInt();
Node n = new Node(value);
stack.push(n);
System.out.println(stack);
}
else if(x == 2){
stack.pop();
}
else if(x == 3){
System.out.println(stack.peek());
}
}
}
static class Node{
int data;
public Node(int data){
this.data = data;
}
}
}
You need to override the default toString method (inherited from Object see API here ) in your Node class, something like this:
static class Node {
int data;
public Node(int data){
this.data = data;
}
#Override
public String toString() {
return "Node: "+data;
}
}
The toString method is used when you try to print the object as a String. If you don't have one, it will use the Object's one which builds a String this way
getClass().getName() + '#' + Integer.toHexString(hashCode()))
and gives you something like Problem1$Node#3d4eac69

Binary Search Trees : how can I compare variable's values of its elements?

So I have a BST and its elements are type TreeNode. Each TreeNode object includes a WordFreq object which consists of a String variable called word, and an integer variable called freq. The elements are words that my program reads from a file, so the variable "word" is that String, and variable freq represent the frequency that the word appears in the text. So what i want to do is go through the whole BST and find the TreeNode with the max frequency(max freq). I tried many ways, but it doesnt seem to work. The words are sorted on the tree alphabetically, NOT sorted by frequency. Here is my method:
public WordFreq getMaximumFrequency() {
return getMaximumFrequencyR(head, 1);
}
public WordFreq getMaximumFrequencyR(TreeNode h, int i) {
WordFreq temp = h.getWordFreq();
if (h.getWordFreq().getFreq() > getMeanFrequency()) { //line 3
if (h.l != null) {
if (h.getWordFreq().getFreq() >= i){
i = h.getWordFreq().getFreq();
temp = h.getWordFreq();
getMaximumFrequencyR(h.l, i);
}
}
if (h.r != null) {
if (h.getWordFreq().getFreq() >= i){
i = h.getWordFreq().getFreq();
temp = h.getWordFreq();
getMaximumFrequencyR(h.r, i);
}
}
}
else {
if (h.l != null) {
getMaximumFrequencyR(h.l, i);
}
if (h.r != null) {
getMaximumFrequencyR(h.r, i);
}
}
return temp;
}
getMeanFrequency() is a method that returns average frequency. The comparison on line 3 makes sense because it is required (for my assignment) that when a word has bigger frequency than average frequency of the tree, to be inserted at the root. That means that the maximum frequency I am looking for cannot be somewhere at the bottom of the tree.
(Language is Java)
Do you have any idea how I could make this work?
here are some helpfull method info to better comprehend my code:
class TreeNode:
public class TreeNode {
private WordFreq wf;
private TreeNode l, r;
private int N;
private TreeNode head;
public TreeNode() {
head = null;
l = null;
r = null;
}
public TreeNode(WordFreq wf) {
this.wf =wf;
l = null;
r = null;
N = 0;
}
public void incrSubtree(TreeNode tn) {
tn.N++;
}
public void decrSubtree(TreeNode tn) {
tn.N--;
}
public WordFreq getWordFreq() {
return wf;
}
}
class WordFreq:
public class WordFreq {
private String word;
private int freq;
public WordFreq(String word) {
this.word = word;
freq=1;
}
public String key() {
return this.word;
}
public void freqIncrease(WordFreq w) {
w.freq++;
}
public String toString() {
return "The word " + key() + " has frequency " + getFreq() + ".";
}
public int getFreq() {
return freq;
}
}
The pseudo-code for the algorithm you want is:
maxFrequency(NULL) = 0
maxFrequency(Node) = max(frequency(Node.value),maxFrequency(Node.right),maxFrequency(Node.Left));
It should not be hard to convert this pseudo-code to java.
Note that this does not take advantage of the fact that a node with above average frequency is inserted at the root. I do not think that it is easy to implement an algorithm that does.
If you need to do an exhaustive search of the tree (i.e. the highest frequency word could be anywhere) then this becomes relatively easy I believe.
However, first of all I suggest you don't set your l and r members to null in TreeNode. Instead I suggest you have a private static EMPTY TreeNode which overrides appropriate methods to play the part of null - such as returing a word frequency of 0. There are lots of reasons to do it this way but rather than list them I suggest you google it! I'm going to assume you've done that in the code below as it makes things a lot neater.
Add a TreeNode method:
public TreeNode maxFrequency() {
return Arrays.asList(this, l.maxFrequenc(), r.maxFrequency()).stream()
.max((tn1, tn2) -> tn1.wf.compareTo(tn2.wf))
.orElse(EMPTY);
}
Let me explain how this works in case you are not experienced with Java 8 streams. The Arrays.asList line creates a list of the current node and the maximum word frequency nodes from the left and right and then turns them into a stream. The max statement finds the one with the highest word frequency using a compareTo method (which you will need to add to the WordFrequency class). This returns a Optional<TreeNode> which could potentially be not present so the orElse statement returns EMPTY if there is no maximum.
Finally you'll need to override this maxFrequency method in the EMPTY TreeNode to just return this to avoid infinite recursion.

Scanner input accepting Strings skipping every other input inside a while loop. [duplicate]

This question already has an answer here:
How to use java.util.Scanner to correctly read user input from System.in and act on it?
(1 answer)
Closed 7 years ago.
Alright, so the code is pretty straight forward. Generic class ourSet, that takes in some elements, puts it in a LinkedList, and does some functions on the two sets.
My problem is actually quite unrelated the general concept of the project, its more in the "user input interface" I've created. I want it to take in some Strings and add it to the set, then while receiving the string "EXIT" (all caps), to exit the loop, and do the same for the next set. What is happening is that the do while loop is only sending the 1st, 3rd, 5th,.. for all odd numbers.
package set.pkgclass;
import java.util.Scanner;
import java.util.LinkedList;
public class SetClass {
public static void main(String[] args) {
ourSet<String> set1 = new ourSet<String>();
ourSet<String> set2 = new ourSet<String>();
Scanner input = new Scanner(System.in);
System.out.println("Please enter a string to put in set 1, "
+ "type EXIT (in all caps) to end.");
do {
set1.add(input.nextLine());
}
while (!"EXIT".equals(input.nextLine()));
System.out.println("Please enter a string to put in set 2, "
+ "type EXIT (in all caps) to end");
do {
set2.add(input.nextLine());
}
while (!"EXIT".equals(input.nextLine()));
ourSet.intersection(set1,set2);
ourSet.difference(set1, set2);
ourSet.union(set1, set2);
}
}
class ourSet<T>{
private LinkedList<T> mySet = new LinkedList<>();
public void add(T element){
mySet.add(element);
}
public void remove(T element){
mySet.remove(element);
}
public boolean membership(T element){
if(mySet.contains(element) == true) {
return true;
}
else {
return false;
}
}
public static <T> void union(ourSet<T> s1, ourSet<T> s2){
System.out.print("The union is: ");
for (int i=0; i < s1.mySet.size(); i++) {
T t = s1.mySet.get(i);
if (!s2.mySet.contains(t)){
s2.add(t);
}
}
for (int i=0; i < s2.mySet.size(); i++){
T t = s2.mySet.get(i);
System.out.print(t+", ");
}
System.out.println();
}
public static <T> void intersection(ourSet<T> s1, ourSet<T> s2){
System.out.print("The intersection is: ");
for (int i=0; i < s1.mySet.size(); i++) {
T t = s1.mySet.get(i);
if (s2.mySet.contains(t)) {
System.out.print(t+", ");
}
}
System.out.println();
}
public static <T> void difference(ourSet<T> s1, ourSet<T> s2){
System.out.print("The difference is: ");
for (int i=0; i < s1.mySet.size(); i++) {
T t = s1.mySet.get(i);
if (!s2.mySet.contains(t)) {
System.out.print(t+", ");
}
}
System.out.println();
}
}
The reason is, you're calling input.nextLine() twice:
do {
set1.add(input.nextLine());
}
while (!"EXIT".equals(input.nextLine()));
A much easier way than do-while is while:
while (!(String in = input.nextLine()).equals("EXIT")) {
set1.add(in);
}
You ask for input twice
do {
set1.add(input.nextLine()); // you enter a number
}
while (!"EXIT".equals(input.nextLine())); // what if you enter another number?
// it'll just loop again, skipping that number
You need to ask for input once and use that either to stop or add it to your set.
You loop is doing exactly what you've told it to...
Read a line of text and add it to set1
Read a line of text and check to see if it equals "EXIT"
Repeat as required...
So, every second request is being used to check for the exit state. Instead, you should assign the text from the input to a variable and use it to do you checks, for example...
do {
String text = input.nextLine();
if (!"EXIT".equals(text)) {
set1.add();
}
} while (!"EXIT".equals(text));
ps- Yes, I know, you could use break ;)

Categories

Resources