So I've been stuck trying to get my array list to print out in the right order but it keeps printing the original input i inserted backwards for some reason, i've tried reading the array in reverse order but it doesn't work either.
public static void Add()
{
System.out.println("You may now enter your virtual diary entry...");
System.out.println("You may END the program at any time by typing in endp...\n");
boolean loop = true;
while(loop)
{
String Stop = Cons.nextLine();
if (Stop.equals("endp")| Stop.equals(""))
{
readelements();
break;
} else {
for (int i =0 ; i <= Notes.size(); ) {
Notes.add(i, Stop);
i++;
break;
}
}
}
}
public static void readelements()
{
if (Empty()) {
Empty();
}
for(int i =0; i < Notes.size(); i++) {
System.out.println(i + " = " + Notes.get(i).toString());
Notes.toString();
}
}
In your else block, you break after one iteration (when i = 0) so you're always running Notes.add(0, Stop). This prepends Stop to Notes, so Notes will be in reverse order. Removing the break will cause you to insert duplicate elements into Notes (note that you're looping but always inserting Stop). Try changing your entire else block to just Notes.add(Stop);. This will add the current value of Stop to the end of Notes and should fix your problem.
Related
Recently, I tried to write a Java program which searches for the minimum of an array.
I tried to write it in a different way, I know there are more simple ways to do that but I want to know why my program does not work.
Here is the source code :
public int minimum(int [] t) {
int min,i,j;
i=j=t.length/2;
min=t[t.length/2];
while(j!=0 || i!=t.length-1) {
while( t[i]>=min) {
i++;
if(i==t.length) {
i=t.length-1;
continue;
}
}
while(t[j]>=min) {
j--;
if(j==-1) {
j=0;
continue;
}
}
if(t[i]<=min && t[j]<=min) {
if(t[i]<=t[j]) min=t[i];
else min=t[j];
}
}
return min;
}
Thanks.
Before you read the answer you should try debugging your code to figure this out by yourself.
I think your code loops infinitely in one of those inner while loops because the end condition
if(i==t.length) {
i=t.length-1;
continue;
}
only resets the i one step back and the continue restarts the while loop. You probably meant to have the break keyword there instead of the continue in which case your code will continue with the other inner while loop.
there is some logic errors in my code , and it get infinitely going through the two loops , i fixed the loops by changing continue with break and i modify the last condition by setting || instead of && (that was a logic mistake), and it works now .
thanks guys.
here is the new source code:
public int minimum(int [] t) {
int min,i,j;
i=j=t.length/2;
min=t[t.length/2];
while(j!=0 || i!=t.length-1) {
while( t[i]>=min) {
i++;
if(i==t.length) {
i=t.length-1;
break;
}
}
while(t[j]>=min) {
j--;
if(j==-1) {
j=0;
break;
}
}
if(t[i]<=min || t[j]<=min) {
if(t[i]<=t[j]) min=t[i];
else min=t[j];
}
}
return min;
}
I have a for loop similar to the one given below.
for(int i=0; i<10; i++)
{
boolean condition = checkCondition(); /* line 3 */
if(condition)
{
if(some other condition A)
{
move to line 3;
}
else if(some other condition B)
{
call_method_B();
}
else
{
call_method_C();
}
}
else
{
call_method_D();
}
}
How do I make the program go back to line 3 within the if statement as above? I don't want to break the iteration. Needs to be in the same iteration and only need move back to line 3.
to be in the same iteration, just subtract i by 1 before you call continue.
do note that this will get you into an infinite loop if the condition is never changed.
for(int i=0; i<10; i++)
{
boolean condition = checkCondition(); /* line 3 */
if(condition)
{
if(some other condition A)
{
move to line 3;
i--; //this will cancel out the i++ in the for loop
continue; //this will bring you back to line 3
}
... the rest of your codes
I don't want to break the iteration. Needs to be in the same iteration and only need move back to line 3.
I think you need a while loop. Then you have more control over when you iterate. When you get the conditionA check, then i doesn't change, and the loop repeats, otherwise you can say i++.
int i = 0;
while (i < 10) {
if (checkCondition()) {
if (some other condition A) {
// continue the iteration
} else if (some other condition B) {
call_method_B();
i++;
} else {
call_method_C();
i++;
}
} else {
call_method_D();
i++;
}
}
I believe your problem seems to need a recursive approach instead of an iterative approach.
The above problem can be solved using a recursive approach in the following way:
public void checkRecursive()
{
boolean condition = checkCondition();
if (base_condition_to_avoid_recursion)
return;
if (condition)
{
if (some other condition A)
{
checkRecursive();
}
else if (some other condition B)
{
call_method_B();
}
else
{
call_method_C();
}
}
else
{
call_method_D();
}
}
So I have written a code that allows a user to find a word in a TextArea. I have nearly succeeded but for one thing. here, I will show you all the code and tell my problem.
if(ta.getText().length() != 0 && t1.getText().length() != 0)
{
char c1[] = ta.getText().trim().toCharArray();
char c2[] = t1.getText().trim().toCharArray();
for(int i=startFlag;i<c1.length;i++)
{
if(c1[i]==c2[0])
{
start = i;
break;
}
}
k=start;
for(int i=0;i<c2.length;i++)
{
if(c2[i] != c1[start++])
{
}
else
countFlag++;
}
if(countFlag==c2.length)
{
ta.select(k,c2.length);
startFlag++;
}
}
For reference, ta is the TextArea and t1 is the TextField where the user enters a word to find. i have a problem in the second for loop. What should I write in the if () block there so that whenever c2[i] != c1[start++] the control is shifted to the first for loop, that would again determine the value of start?
Create a method to get "start" that you can then call whenever you want.
if(ta.getText().length() != 0 && t1.getText().length() != 0)
{
char c1[] = ta.getText().trim().toCharArray();
char c2[] = t1.getText().trim().toCharArray();
k=getStart(startFlag, c1.length);
for(int i=0;i<c2.length;i++)
{
if(c2[i] != c1[start++])
{
start = getStart(startFlag, c1.length);
}
else
countFlag++;
}
if(countFlag==c2.length)
{
ta.select(k,c2.length);
startFlag++;
}
}
And getStart() is:
public int getStart(int startFlag, int length) {
for(int i=startFlag;i<length;i++)
{
if(c1[i]==c2[0])
{
return i;
}
}
}
You may need different inputs to getStart(), but hopefully this gets across the general idea.
The way your code is set up right now, what you're asking for is impossible. To do what you're asking, you'll need to refactor your current code into different methods. More specifically, you'll need to put the for loops into their own methods and then call these methods.
So what you would need to do is make a separate method for the for loop.
public static int startForLoop(int i) {
for(int i=startFlag;i<c1.length;i++)
{
if(c1[i]==c2[0])
{
start = i;
break;
}
}
}
Then you can just call startForLoop(0) initially and in the 2nd for loops if statment:
if(c2[i] != c1[start++])
{
startForLoop(start+1)
}
This will continue the for loop where it left off. If you need to run the 2nd for loop again then you have to make a separate method for it as well and basically place both of them in a while loop that continues till you find the result you want in the 2nd for loop.
May be this code piece help you what you are looking for.
Basically it moves along with the string to be searched in keeping in mind the index of the string to be searched for.
Sorry but i have implemented it in java, but the notion is same and the result returned is the best what i got.you must give it a try!
private static String searchString(String searchIN,String searchFOR){
if (searchFOR != "") {
int index = searchIN.toUpperCase().indexOf(searchFOR.toUpperCase());
String before = "";
String highlighted = "";
String after = "";
while (index >= 0) {
int len = searchFOR.length();
before = searchIN.substring(0, index);
highlighted = "\"" + searchFOR + "\"";//do what ever you want to do with searched string
after = searchIN.substring(index + len);
searchIN = before + highlighted + after;
index = searchIN.toUpperCase().indexOf(searchFOR.toUpperCase(), index + highlighted.length());
}
}
return searchIN;
}
I am writing program that asks user to type seven names of product.
what I try to do is if there is duplicate, then repeat the method.
I used while loop but I stuck.
If I put a,b,c,d,e,f,g at the first time, method ends and moves on to next method.
But if I typed a,a,b,c,d,e,f, program repeats same method and even if I type a,b,c,d,e,f,g, it gets in infinite loop.
here is my codes.
in main....
purchasedList.setShopList();
in purchasedList class...
public void setShopList() {
Scanner keyboard = new Scanner(System.in);
// print out description.
System.out.println("\n- Only have one entry of any type in the item list.");
System.out.println("- The name of items cannot be longer than 16 characters.");
System.out.println("\nType seven products.");
boolean sameNames = true;
while (sameNames == true) {
for (int i=0; i<7; i++) {
String n = keyboard.nextLine();
name.add(n);
name.set(i,name.get(i).toUpperCase());
}
sameNames = checkName();
}
}
// accessor.
public ArrayList<String> getShopList () {
return name;
}
// check duplicate.
public boolean checkName() {
Set<String> uniqueName = new HashSet<String>();
boolean foundName = false;
for (int i=0; i<7; i++) {
if (!uniqueName.add(name.get(i))) { // check duplicate
foundName = true;
}
}
if (foundName == true) {
System.out.println("※ There is a duplicate. Try it again.");
return true;
} else {
return false;
}
}
my checkName() method is fine because in my last project it worked.
in my last project, I put while loop in main like this
public static void main(String[] args) {
PurchasedList purchasedList = new PurchasedList();
.
.
.
boolean sameNames = true;
boolean tooLong = true;
while (sameNames == true || tooLong == true) {
System.out.println("\nType seven products.");
purchasedList.setShopList();
sameNames = purchasedList.checkName();
tooLong = purchasedList.checkLength();
}
but this time, because my professor wants me to make all operations are done within a method, so I try to fix.
I tried to solve it by myself in last 8 hours, but I could not get the solution.
Please help me.
Thank you.
add this line.
if (foundName == true) {
System.out.println("※ There is a duplicate. Try it again.");
-> name = new ArrayList<String>();
return true;
right now you are adding new names to the end of the array, and then setting them to upper case in the start of the array.
for (int i=0; i<7; i++) {
String n = keyboard.nextLine(); //Say I type in g on my second try
name.add(n); //This add g to the end of the array
name.set(i,name.get(i).toUpperCase()); //And this sets name[0] to G.
}
this means your name array is getting longer, instead of resetting.
Do you ever clean name? It appears you just keep adding to it, so the previous entrances are still there in loop's next round. And therefore there will always be a duplicate if you use same input as before (the order will not matter).
This change should do it:
while (sameNames == true) {
name = newArrayList <String>();
for (int i=0; i<7; i++) {
String n = keyboard.nextLine();
name.add(n);
name.set(i,name.get(i).toUpperCase());
}
sameNames = checkName();
}
So new name ArrayList is created every time. (Garbage collector will take care of the old ones, if necessary.) If name is already created somewhere else, then think if you really need it there - as far as I see you use it to gather input, and this happens in the method setShopList() so it appears you do not need it earlier than this.
for(int x = 0;x<14;x++){
day[x]= theSheet.changeLetters(day[x]);
}
public String changeLetters(String entering){
if(entering.equalsIgnoreCase("a")){
entering = "10";
} else {
if(entering.equalsIgnoreCase("b")){
entering = "11";
} else {
if(entering.equalsIgnoreCase("c")){
entering = "12";
} else {
if(entering.equalsIgnoreCase("d")){
entering = "13";
} else {
if(entering.equalsIgnoreCase("e")){
entering = "14";
} else {
if(entering.equalsIgnoreCase("f")){
entering = "15";
} else {
if(entering.equalsIgnoreCase("g")){
entering = "16";
} else {
if(entering.equalsIgnoreCase("h")){
entering = "17";
}
}
}
}
}
}
}
}
return entering;
}
Says the error is here if(entering.equalsIgnoreCase("a")) and in the for loop I am using to run the method. I'm trying to change the letter put into the string into a number.
Can anyone explain to me where the error might be? I'm having trouble spotting the issue. it lets me enter the letters fine but it has an exception once it gets to this for loop and runs this method.
why don't you use
if (condition) {
// ...
} else if (condition2) {
// ...
} else if (condition3) {
// ...
}
// and so on
to make your code more readable. Your nested conditions are a mess. If you fix them, you might as well fix the error (if it's in the part of code you showed us).
Also add
System.out.println("Entering = '" + entering "'");
at the beginnig of your method to see if really receives what you are expecting it to receive.
Ok according to
Yes the code is being initialized in a for loop before that one using
for(int x =1;x<8;x++){ day[x-1] = JOptionPane.showInputDialog("Enter
hour pairs for day "+x +".\n Enter the first digit: "); day[x] =
JOptionPane.showInputDialog("Enter the second digit: "); } the letters
being put in the array are then changed into numbers using the for
loop posted earlier.
You have a logic error. You are overwriting previous entries and not filling the array up to 14 items. So items after 8 are left null, thus the NullPointerException.
Try this:
String[] day = new String[14];
for( int i = 0; i < 14; i+=2 ) {
day[i] = JOptionPane.showInputDialog("Enter hour pairs for day "+(i/2+1) +".\n Enter the first digit: ");
day[i+1] = JOptionPane.showInputDialog("Enter the second digit: ");
}
As a bonus, you can simplify the if-else code with:
public String changeLetters( String entering ) {
return String.valueOf(entering.toUpperCase().charAt(0) - 55);
}
As #jlordo already stated avoid nested if-statements with such a depth.
As an alternative you might use a switch statement in combination with an enum like this - although the following approach consists of more code it is more general and better suitable to be extended (e.g. using all letter of the alphabet and beyond) and it would make the code much more readable and more appropriate with respect to what you want to express.
Letter letter;
if (letter.equals("a")) letter = Letter.a;
if (letter.equals("A")) letter = Letter.A;
// and so on ...
switch (letter) {
case a : {
// do some code here ...
break;
}
case A : {
// do some code here ...
break;
}
// and so on ...
}
public enum Letter {
a (1),
A (2),
b (3),
B (4),
c (5),
C (6);
// and so on
private final int index;
Letter(int i) {
index = i;
}
public int getIndex () {
return index;
}
}
Note that if you're using Java 7 you can use the switch statement even without the enum since it accepts strings as well like this:
switch (entering) {
case "a" : {
// ...
}
// ...
}