Need help in Computer Science....

Silencer

CAGiversary!
Feedback
3 (100%)
I'm working with linked lists and need to write a "copy" method in both recursive and iterative form.

Copy just returns a copy of the given linked-list string
So, the recursive form would be:

public static StringNode copy (StringNode str) {

if (str == null)
return null;

StringNode copyFirst = new StringNode(str.ch, null);
copyFirst.next = copy(str.next);
return copyFirst;

}

but I need help on writing it in the iterative form (while, for, loops, etc).
How should I start it? Do I need two references -- one has a trav and the other who follows behind?
 
It seems like every week we get someone taking a computer science course who needs help with a program.

I'm not sure what exactly you're asking for. You just want to write a loop?
 
The string is just an array of characters so use a for loop.


String str; // original string
String str2; // returned copy string

String CopyString (String string)
{
String str2;
for (i=0; i >= str.length; ++i)
{
str = str2;
}
return str2;
}
 
I'm not familiar enough with Java to give you any real code, but I would imagine you could just do a "for i=0 to length of list" or "while str != null" (looping on str = str.next)

I'm probably oversimplifying since I haven't done these kind of CS assignments in 5 years, but iteratively all you need to do is construct a new linked list as you run through that loop.
 
1. Get the size of str
2. Use a while loop or for loop that will run once for every entry in str (use the size and an incrementing int to do this)
3. For each iteration get the current entry of str and add it to the end of copy.
4. ...
5. profit

There are probably built in methods to do all of those tasks (size of the list, get spedific entry, append to the end of a list)
 
Ok..so would something like this do the trick:

public static StringNode copy(StringNode str) {

for (StringNode curr = str; curr != null; curr = curr.next){
curr.ch = str.ch;

return curr;
}
return null;
}

?

I also need to make one last method called "concat" which takes two string StringNodes and fuses them together.
Again, I did it recursively:

public static StringNode concat(StringNode str1, StringNode str2) {
StringNode cat;

if (str1 == null)
cat = copy(str2);
else
cat = new StringNode(str1.ch, concat(str1.next, str2));

return cat;
}

but could use some help doing it iteratively.
 
If using a stringNode in a for loop like that is kosher than that looks good. Pretty elegant approach. Although doesn't calling StringNode curr = str do the copy right in your initialization? basically skipping the need to have a loop? I'm not sure of the classdef for StringNode so I'm not sure exactly what would be happening.

It's interesting that you have an easier time coming up with a recursive approach vs. an iterative approach. It was always the opposite for me.

For the concat just use the same iterative solution you come up with to do a copy and simply call it for both of the passed in strings in sequence. I think that would work.
 
This won't be helpful at all, but fuck LINKED LISTS.

I can't stand when my assignments are linked lists. One reason I didn't use A* for my pathfinding assignment.
 
[quote name='wubb']If using a stringNode in a for loop like that is kosher than that looks good. Pretty elegant approach. Although doesn't calling StringNode curr = str do the copy right in your initialization? basically skipping the need to have a loop? I'm not sure of the classdef for StringNode so I'm not sure exactly what would be happening.

It's interesting that you have an easier time coming up with a recursive approach vs. an iterative approach. It was always the opposite for me.

For the concat just use the same iterative solution you come up with to do a copy and simply call it for both of the passed in strings in sequence. I think that would work.[/QUOTE]

Sorry, when you say call it for both, do you mean the copy() method?
 
OP, if you are going to claim to be able to write something recusively, don't let someone else find the same thing on google okay?

http://cs-people.bu.edu/alexst/TF/Fall06/StringNode.java

/**
* copy - returns a copy of the given linked-list string
*/
public static StringNode copy(StringNode str) {
if (str == null)
return null;
StringNode copyFirst = new StringNode(str.ch, null);
copyFirst.next = copy(str.next);
return copyFirst;
}


If you truely understood any of this, writing an iterative form of a copy method wouldn't be that hard.

Oh, and your concat method is on the same page I linked to above.

Word to the wise. Learn what iteration is before you claim to understand recursion.
 
^^ :lol:

You wouldn't be able to call the copy method straight up twice in a row since I think it initializes the returned string each time it's called. (So you'd end up with just a copy of the 2nd string.)

But you could reuse the code from the copy (copying it's loop in your new method twice) and modify the 2nd loop so it starts with an already built up input stringnode rather than initializing it fresh.

I do think you may need to modify the copy you posted up there.

Does calling

StringNode copy = str; set copy = to str right from that call. If so that's doing the copy and the loop is superflous.

I was thinking of something like

for (int i = 0; i < length of str; i++) {
copy.add(str.get(i));
}

But I don't know if add and get are methods for StringNode. They are for the LinkedList class. Then for a concat you'd just have a 2nd for loop after that one.

Ah okay I think StringNode.next; advances (a built in cursor or something?) one char in a StringNode and StringNode.ch returns the current character of the StringNode. So I think every iteration of your for loop should do something like

copy.next = str.ch;
str.next;

But you probably have to play around a bit to get that to really work.
 
i tried testing out my copy method in the main method and it works. I'm just not sure if it's just returning the str or actually making a "copy"
 
I think the StringNode curr = str in the for loop is doing the copy right there... Try reducing your method to just that statement (no loop) and see if it still returns a copy. If not then you probably have it. If so then you need to rework it to really do the copy in a loop.
 
Wubb, StringNode isn't a native Java class. It isn't part of the spec (5.0 API) and I doubt the OP knows anything about it more than what he stole from the page I linked.

Kids like this used to crack me up back in school. They might eventually luck up and find this assignment somewhere, but eventually they get busted.

[quote name='Silencer']i tried testing out my copy method in the main method and it works. I'm just not sure if it's just returning the str or actually making a "copy"[/quote]

This isn't "your" copy method. This is some code you found on the net. I hope you actually get this working, turn it in, and fail when you realize that probably 3 more kids in your class will have this exact same code.

OP, answer me this. Which programming class is this for? Intro to Java II? Did your professor say to use a "StringNode"? Do you know what a "StringNode" even is?
 
[quote name='mtxbass1']Wubb, StringNode isn't a native Java class. It isn't part of the spec (5.0 API) and I doubt the OP knows anything about it more than what he stole from the page I linked.

Kids like this used to crack me up back in school. They might eventually luck up and find this assignment somewhere, but eventually they get busted.[/QUOTE]


The recursive methods was given to us, what I posted is what is given -- the assignment is to take the recursive methods and turn them into iterative
 
Then if you understand recursion, you should easily be able to translate this into an iterative form.

I love how your story has changed from, "I am able to do this recursively" to "this is what is given to us".

Dude, fess up. If you don't understand how stuff works, just ask. Iteration is a quite simple concept if explained right. Don't just come on here asking for help and expect one of us to solve it for you. It won't do you any good, even if you do get the solution from us. You'll still be clueless on the next assignment. If there is something you don't understand about it, just ask, but trying to act like you understand recursion, only to not be able to do a simpler process (iteration) is just weak.

I'm not going to write this code for you, but I will give you some help.

Yes you need two nodes. One to create a node, the other to traverse the list. You will want to use a while loop that checks that while your current spot in the list isn't null, do something.
 
You're right and I apologize. I should have explicity stated that the recursive methods were given to us.

We were given a "StringNode" class where 5 or 6 methods were done recursively and asked to change said methods into the iteration form.

i.e., there's a "length()" method which was originally:
public static int length(StringNode str) {
if (str == null)
return 0;
else
return 1 + length(str.next);
}


This was easy to do for me. In iteration, I have it:

public static int length(StringNode str) {

StringNode curr = str;
int length = 0;

while (curr != null){
length++;
curr = curr.next;
}

return length;

}

and it works. Now, I need help with the copy method -- even though it returns a "copy" of a string, it's not actually making a new "copy" I think.
 
Yeah that snippet confirms for me that the StringNode curr = str in the for loop is actually what does the copy as it's how you copy str in your example above.

Use your length method to get the length of str. Use that value as the limit on your for loop. And do the copy of each character in your loop. I think you can work it out if you put your mind to it.
 
[quote name='wubb']Yeah that snippet confirms for me that the StringNode curr = str in the for loop is actually what does the copy as it's how you copy str in your example above.

Use your length method to get the length of str. Use that value as the limit on your for loop. And do the copy of each character in your loop. I think you can work it out if you put your mind to it.[/QUOTE]

that's the problem, there's no explicit way I can find the "length" of a string since I'm working with StringNodes, not Strings.
 
[quote name='mtxbass1']

Yes you need two nodes. One to create a node, the other to traverse the list. You will want to use a while loop that checks that while your current spot in the list isn't null, do something.[/QUOTE]

So, one node equals str and then create a second node? What should I do with the newly created node?
 
[quote name='wubb']Yeah that snippet confirms for me that the StringNode curr = str in the for loop is actually what does the copy as it's how you copy str in your example above.

Use your length method to get the length of str. Use that value as the limit on your for loop. And do the copy of each character in your loop. I think you can work it out if you put your mind to it.[/QUOTE]

public static StringNode copy(StringNode str) {

StringNode curr2 = str;

while (curr2 != null){
for (int i = 1; i < str.length(str)+ 1; i++){
curr2.ch = str.ch;
curr2 = curr2.next;

return curr2;
}
}
return null;

something like this? If I input "FINE" it returns "INE" as the copy though.
 
You're probably overwriting the first value of the copy if that's your output.

This is when debug statements come in handy ;) At every step of that method, write out the value that you are assigning to see what is going on in the logic.
 
You'll want to do something like this OP.

Let's say you have a pre-established StringNode called strNode.

To get the length of this, you should be able to do this.

int length = strNode.toString().length();

Like botticus said, put debug statements everywhere (System.out.println's). This will aid in your program greatly.

And to answer your question, your second node is used to traverse the list.
 
3rd try?

public static StringNode copy (StringNode str) {

StringNode curr = str;
StringNode trav = null;
int length = str.length(str);

while (curr != null){
for (int i = 0; i < length; i++)
trav.ch = str.ch;

curr = curr.next;
}

return trav;
}
 
I believe he's calling the length method he posted earlier (custom created) which does take a StringNode in. (Not the built in length method on the standard String class.)
 
[quote name='wubb']I believe he's calling the length method he posted earlier (custom created) which does take a StringNode in. (Not the built in length method on the standard String class.)[/quote]

Ahh, good catch. Poor implementation, but good catch.

Does your "3rd try" produce results OP?
 
[quote name='mtxbass1']Ahh, good catch. Poor implementation, but good catch.

Does your "3rd try" produce results OP?[/QUOTE]

I tested it out and it gave me null pointer exceptions :(

I tried a different approach on my concat method (without using copy method) and it seems to work:

public static StringNode concat(StringNode str1, StringNode str2) {

StringNode curr = str1;
StringNode curr2 = str2;

while (curr.next != null){
curr = curr.next;
}
curr.next = curr2;
return str1;

}
 
[quote name='mtxbass1']It looks like the code you posted does absolutely nothing to the value of str1...[/QUOTE]

for my concat method? I tested it out and it properly combined the two words..
 
This thread makes me feel dumb. The only two codes I've ever known were basic HTML back in the Geocities days and a VERY SMALL bit of Dark Forces II: Jedi Knight config file hacking. As in screwing things up in online games hacking.
 
[quote name='Silencer']for my concat method? I tested it out and it properly combined the two words..[/quote]

Are you sure you are calling the one you pasted?

Paste your entire program here and I'll test it.
 
[quote name='mtxbass1']Are you sure you are calling the one you pasted?

Paste your entire program here and I'll test it.[/QUOTE]

i'll send it via pm.
 
import java.io.*;
import java.util.*;

/**
* A class for representing a string using a linked list. Each
* character of the string is stored in a separate node.
*
* This class represents one node of the linked list. The string as a
* whole is represented by storing a reference to the first node in
* the linked list. The methods in this class are static methods that
* take a reference to a string linked-list as a parameter. This
* approach allows us to use recursion to write many of the methods.
*/
public class StringNode {
private char ch;
private StringNode next;

/**
* Constructor
*/
public StringNode(char c, StringNode n) {
ch = c;
next = n;
}

/**
* getNode - private helper method that returns a reference to
* node i in the given linked-list string. If the string is too
* short, returns null.
*/
private static StringNode getNode(StringNode str, int i) {

StringNode curr = str;
int x = 0;


while (curr != null){
if (x == i)
return curr;
else
x++;
curr = curr.next;
}
return null;
}

/*****************************************************
* Public methods (in alphabetical order)
*****************************************************/

/**
* charAt - returns the character at the specified index of the
* specified linked-list string, where the first character has
* index 0. If the index i is < 0 or i > length - 1, the method
* will end up throwing an IllegalArgumentException.
*/
public static char charAt(StringNode str, int i) {
if (str == null)
throw new IllegalArgumentException("the string is empty");

StringNode node = getNode(str, i);

if (node != null)
return node.ch;
else
throw new IllegalArgumentException("invalid index: " + i);
}

/**
* concat - returns the concatenation of two linked-list strings
*/
public static StringNode concat(StringNode str1, StringNode str2) {

StringNode curr = str1;
StringNode curr2 = str2;

while (curr.next != null){
curr = curr.next;
}
curr.next = curr2;
return str1;

}
/**
* convert - converts a standard Java String object to a linked-list
* string and returns a reference to the linked-list string
* (non-recursive)
*/
public static StringNode convert(String s) {
if (s.length() == 0)
return null;

StringNode firstNode = new StringNode(s.charAt(0), null);
StringNode prevNode = firstNode;
StringNode nextNode;

for (int i = 1; i < s.length(); i++) {
nextNode = new StringNode(s.charAt(i), null);
prevNode.next = nextNode;
prevNode = nextNode;
}

return firstNode;
}

/**
* copy - returns a copy of the given linked-list string
*/
public static StringNode copy (StringNode str) {

if (str == null)
return null;

StringNode copyFirst = new StringNode(str.ch, null);
copyFirst.next = copy(str.next);
return copyFirst;
}

// StringNode curr = str;
// StringNode trav = null;
// int length = str.length(str);
//
// while (curr.next != null){
// for (int i = 0; i < length; i++)
// trav.ch = str.ch;
//
// curr = curr.next;
// }
//
// return trav;
// }

public static StringNode reverse (StringNode str){

StringNode firstNode = str;
StringNode reverseNode = null;

while (firstNode != null){
StringNode secondNode = firstNode.next;
firstNode.next = reverseNode;
reverseNode = firstNode;
firstNode = secondNode;
}

return reverseNode;
}

/**
* deleteChar - deletes character i in the given linked-list string and
* returns a reference to the resulting linked-list string
*/
public static StringNode deleteChar(StringNode str, int i) {
if (str == null)
throw new IllegalArgumentException("string is empty");
else if (i < 0)
throw new IllegalArgumentException("invalid index: " + i);
else if (i == 0)
str = str.next;
else {
StringNode prevNode = getNode(str, i-1);
if (prevNode != null && prevNode.next != null)
prevNode.next = prevNode.next.next;
else
throw new IllegalArgumentException("invalid index: " + i);
}

return str;
}

/**
* indexOf - returns the position of the first occurrence of
* character ch in the given linked-list string. If there is
* none, returns -1.
*/
public static int indexOf(StringNode str, char givenCh) {

StringNode curr = str;
int index = 1;

while (curr != null){
if (curr.ch != givenCh){
index++;
curr = curr.next;
}
else{
break;
}
}

return index;
}

/**
* insertChar - inserts the character ch before the character
* currently in position i of the specified linked-list string.
* Returns a reference to the resulting linked-list string
*/
public static StringNode insertChar(StringNode str, int i, char ch) {
StringNode newNode, prevNode;

if (i < 0)
throw new IllegalArgumentException("invalid index: " + i);
else if (i == 0) {
newNode = new StringNode(ch, str);
str = newNode;
} else {
prevNode = getNode(str, i-1);
if (prevNode != null) {
newNode = new StringNode(ch, prevNode.next);
prevNode.next = newNode;
} else
throw new IllegalArgumentException("invalid index: " + i);
}

return str;
}

/**
* length - recursively determines the number of characters in a
* linked-list string
*/
public static int length(StringNode str) {

StringNode curr = str;
int length = 0;

while (curr != null){
length++;
curr = curr.next;
}

return length;

}

/**
* print - recursively writes a linked-list string to System.out
*/
public static void print(StringNode str) {
if (str == null)
return;
else {
System.out.print(str.ch);
print(str.next);
}
}

/**
* read - reads a string from standard input and returns a
* reference to a linked list containing the characters in the string
*/
public static StringNode read() {
Scanner scan = new Scanner(System.in);
return convert(scan.nextLine());
}

/**
* toUpperCase - converts all of the characters in the specified
* linked-list string to upper case
*/
public static void toUpperCase(StringNode str) {
StringNode trav = str;
while (trav != null) {
if (trav.ch >= 'a' && trav.ch
 
Type a string:
ABC
Your string is: ABC
Its length is 3 characters.
What # character to get (>= 0)? 2
That character is C
What character to search for? C
The index of that character is: 3
What # character to delete (>= 0)? 3
The string is too short.
Unchanged copy: ABC
What # character to insert before (>= 0)? 3
What character to insert?
A
The string is too short.

You may want to fix your indexing a little. It told me the index of C was 3, however when I put in that I wanted the second char, it was C...


 
I'm not getting any null pointers when I run it. I just don't get quite the correct output. The concat method is fine. What problem are you having OP?
 
Wow, that's some crazy stuff. Do you have a copy of the class as it was given to you? (i.e. without any of your stuff added.)

I think toUpperCase may be a method to look at and model the copy against.

StringNode str2 = str;
creates a new StringNode that points to the same memory as str, so a change in one affects the other. (i.e. if you set str2.ch = 'A' the first char of both nodes will now be A.)

So I'm guessing the point of the copy is to make a deep copy (in other words don't have the resultant variable simply share mem with the source node.)

The concat is simply setting the 1st param = to param1 + param2. Is that really what you want to do, or are you supposed to leave the passed in params unchanged?

For example if you run:

StringNode concat1 = convert ("piece1");
StringNode concat2 = convert ("piece2");
StringNode concat3 = concat (concat1, concat2);
System.out.print("Concat: ");
print(concat1);
System.out.println();
print(concat2);
System.out.println();
print(concat3);
System.out.println();

System.out.println();

concat3.ch = 'X';
print(concat1);
System.out.println();
print(concat2);
System.out.println();
print(concat3);
System.out.println();

You'll see that both concat1 and concat3 are the result and they both share the same mem (Both have their first char changed to X.) Using a lot of prints is the best way to debug.

But the given recursive copy method creates a new StringNode that does not share memory as shown with this code (right below the above)

StringNode copytest = copy(concat3);
copytest.ch='Y';

System.out.println();
System.out.println("copytest:");
print(copytest);
System.out.println();
print(concat3);
System.out.println();

concat3's first char is not changed to Y.
 
mxt, the first character is considered to be at index "0" so you may be off by one because of that (also why it said the string was too short for you)

The only problem I have remaining is copy method. I'm just not sure how to turn it into it's iteration form.
 
[quote name='Silencer']mxt, the first character is considered to be at index "0" so you may be off by one because of that (also why it said the string was too short for you)

The only problem I have remaining is copy method. I'm just not sure how to turn it into it's iteration form.[/quote]

Trust me, I know how indexing works. Follow the output I provided.

What # character to get (>= 0)? 2
That character is C
What character to search for? C
The index of that character is: 3


Your program tells me that C is the second char (since it starts at 0).
When I put C back in, it says the index is 3...
 
[quote name='mtxbass1']Trust me, I know how indexing works. Follow the output I provided.

What # character to get (>= 0)? 2
That character is C
What character to search for? C
The index of that character is: 3


Your program tells me that C is the second char (since it starts at 0).
When I put C back in, it says the index is 3...[/QUOTE]


ok thanks, I fixed it now, I had int index = 1; in my indexOf method for some reason.
Thanks for catching that.
 
StringNode trav = null;
int length = str.length(str);
while (curr.next != null){
for (int i = 0; i < length; i++)
trav.ch = str.ch;

See the problem?
trav is null, but you are trying to say trav.ch = str.ch. Trav was never initialized.
 
[quote name='mtxbass1']StringNode trav = null;
int length = str.length(str);
while (curr.next != null){
for (int i = 0; i < length; i++)
trav.ch = str.ch;

See the problem?
trav is null, but you are trying to say trav.ch = str.ch. Trav was never initialized.[/QUOTE]


so would it be:

trav.next.ch = str.ch;
?
 
no. Let me give you a simple example.

String word = null;

System.out.println(word.length());

This would throw a null pointer exception.

String word = null;
word = "test";
System.out.println(word.length());

This wouldn't.

See the difference? You need to initialize trav in your code.

StringNode trav = null; declares the variable. It still must be initialized.
 
bread's done
Back
Top