I am a beginner and I know I'm making a rookie mistake. I have the following code in my actionePerformed part of my JApplet. the if statement within the for loop is supposed to search for the matching name in array s[] (t6 is a JtextArea) and assign the value of int m to int n, so i can retireve all the information of s[i]. problem is that my n is always 0 not matter what!!! What am I doing worng?
if (e.getSource() == b7) {
for(int m=0; m>i ; m++){
if(t6.getText().equals(s[m].getName())){
n=m;
}
}
String text1 = "";
text1 += s[n].getName().toString() + ", average=" + s[n].getAvgMark()
+ ", " + s[n].getProgramName().toString() + ", "
+ s[n].getDegree()+ ", " + s[n].getUni1() +"-"+ s[n].getStatus0()
+", "+ s[n].getUni2()+"-"+ s[n].getStatus1() + ", "
+ s[n].getUni3()+"-"+ s[n].getStatus2()+"\n";
ta2.setText(text1);
}
I bet you problem is that you you start int n = 0.
Look at your loop
for(int m=0; m>i ; m++){
Th only way this will not be an infinite loop is if i is 0 or less. Which I'll assume it is do to you not getting an infinite loop. And since you're not getting an ArrayIndexOutOfBoundsException I'll assume that i is 0 and not a negative. Therefore
for(int m=0; m>i ; m++){
states that continue the loop if m is greater than 0, which it never is.
So your array index will only be 0 once. It never loops.
Even if you i++, m will NEVER be greater than i because they start evenly and would be incremented evenly.
Just a hunch
Maybe you want this
for(int m = 0; m < s.length ; m++){
// iterates [size of the s array] times
Your code would be easier to debug if you used more descriptive variable names, and you didn't chain and concatenate so much in one statement. You can be a little more verbose; it isn't a competition to write the shortest or most obscure code!
I also suggest you initialize the variable, and prepare for failure.
int matchingIndex = 0; // initialize that variable!
int upperBound = myList.legnth;
for(int m=0; m > upperBound; m++){
String sourceText = searchSource.getText();
String thisName = myList[m].getName();
if(sourceText.equals(thisName)){
matchingIndex = m;
}
}
if (matchingIndex < 1) {
outputElement.setText('No match'); // or some other way to display the error
return;
}
... you see there, I renamed the obscure n to matchingIndex, the secretive t6 to searchSource, the dubious i to upperBound (and I made sure it is what it should be, the length of myList), questionable ta2 becomes outputElement, and the shy s to myList. I also unchained the calls and matches, and now you can read that code. And, you can output different parts to debug it. Think sourceText SHOULD be matching thisName? Output the values and see what the discrepancy is!
Finally, I added some logic to deal with the distinct possibility that no match is found.
Related
I'm trying to replace the jth value of the function's input string to '0' whenever the ith value of alphabet is contained in the function's input.
I am expecting this for-loop to increment i whenever the alphabet[i] equals input x[j] but it gets stuck at i when it does. What is going on here??
P.S This is an introductory programming course (CS50) and it uses different syntax then standard C.
void checkrepeat(string x)
{
string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int alphalen = strlen(alphabet);
for (int i = 0; i < alphalen; i++)
{
for (int j = 0; j < strlen(x); j++)
{
if (alphabet[i] == x[j])
{
x[j] = '0';
printf("%i,", i);
printf("%c,", alphabet[i]);
printf("%s\n", x);
}
}
}
}
The output of function with value x = 'AAA' gives me
0,A,0AA
0,A,00A
0,A,000
I am expecting it to give me
0,A,0AA
1,B,0AA
2,C,0AA
This is my first post so pardon me if I am too verbose or not following any unsaid rules; I would be happy to include any suggestions as I contribute more.
I could be wrong but looks like "Your expected output pattern" and "your interpretation of assignment" are contradictory.
Let me explain why ?
1 - Expected Output for x='AAA'
I am expecting it to give me
0,A,0AA
1,B,0AA
2,C,0AA
2 - your interpretation of assignment
replace the 'j'th value of the function's input string to '0' whenever the 'i'th value of alphabet is contained in the function's input.
Here you are interpreting whenever as "update input string with '0' for **ALL** matches"
i.e. replace all A's with 0's.
If I follow interpretation [2] then output of your function code "as is" for x='AAA' would print like this
0,A,0AA
0,A,00A
0,A,000
i loop with j=1 will run but nothing is printed because there is no B in input string
i loop with j=2 will run but nothing is printed because there is no C in input string
and this will continue till Z
and the loop will end
BTW - I hope you can see the waste of CPU processing power in your solution.
If your interpretation [2] is correct then your expectation of output [1] is erroneous and vice versa.
ASSUMING interpretation [2] is correct then you need to change your code as below however the output would be different from expected output [1].
void checkrepeat(char x[])
{
char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int alphalen = strlen(alphabet);
for (int i = 0; i < alphalen; i++)
{
for (int j = 0; j < strlen(x); j++)
{
if (alphabet[i] == x[j])
{
x[j] = '0';
}
}
printf("%i,", i);
printf("%c,", alphabet[i]);
printf("%s\n", x);
}
}
And output of your modified function for x='AAA' would print like this
0,A,000
1,B,000
2,C,000
...
25,Z,000
As an example when x='ABCDZABCDZ' then the expected output would look like
0,A,0BCDZ0BCDZ
1,B,00CDZ00CDZ
2,C,000DZ000DZ
3,D,0000Z0000Z
4,E,0000Z0000Z
...
25,Z,0000000000
Open this link to see Working code in C
https://onlinegdb.com/rJhda-gMP
3 - your interpretation of assignment
I am expecting this for-loop to increment the 'i' whenever the alphabet[i] equals input x[j]
Here you are interpreting whenever as "as soon as first match is found update input string with '0' and increment 'i'"
ASSUMING interpretation [3] is correct, following code changes are needed to print your expected output [1]
void checkrepeat(char x[])
{
char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int alphalen = strlen(alphabet);
for (int i = 0; i < alphalen; i++)
{
for (int j = 0; j < strlen(x); j++)
{
if (alphabet[i] == x[j])
{
x[j] = '0';
break;
}
}
printf("%i,", i);
printf("%c,", alphabet[i]);
printf("%s\n", x);
}
}
If I follow interpretation [3] then it meets the expected output [1] and for x='AAA' your function would print like this which
0,A,0AA
1,B,0AA
2,C,0AA
...
25,Z,0AA
As an example when x='ABCDZABCDZ' then the expected output would look like
0,A,0BCDZABCDZ
1,B,00CDZABCDZ
2,C,000DZABCDZ
3,D,0000ZABCDZ
4,E,0000ZABCDZ
...
25,Z,00000ABCDZ
Open this link to see Working code in C
https://onlinegdb.com/rJhda-gMP
Hope it helps.
Firstly, printf("%c,", alphabet[i]);is an error. You probably didn't mean to use the , after %c. Remove it.
Second,Its easy to loose the logic in nested loops, especially as a beginner. Write it down on paper and run through it, If you haven't yet learn about debuggers.
Now,you probably do not want i to ++ when there is a match between alphabet[i]and x[j], because i is your loop counter, and should not be messed with like that (You have likely confused a for loop with a while loop or are coming from something like Scratch).
I would suggest declaring a separate variable, say int x for this task.
As already mentioned in the comments, you haven't actually implemented this incrementation to take place(with a simple x++; in the if statement), and have wrongly assumed that somehow the i++ in your for loop has done it for you .
Again, I'll suggest you to hit the books and go back to see the exact workings of a for loop , which is very frequently used in C , so you cannot afford to be fuzzy on its key concepts.
Also, you seem to expect the string x to remain 0AA ... If this is the case , why would the first statement in you if() be x[j] = '0'; ? This will make every jth element of x that matches with alphabets a '0'.
Further, in the expected output, you have expected alphabet[i] to be A , then B , then C, despite clearly stating in your question that you had passed x as "AAA" (which obviously cannot then match with B or C).
Maybe you haven't written the 'I expect' with clear forethough. Please do not include sample expected output if it is not possible with the code you have supplied in the question. It confused me, and could confuse anyone. I assume you drastically shortened the code for S.O. but supplied the expected output of the original code you have somewehere on your computer.
My book says for programming using while-loop, we must first initialize with a number, provide the condition mentioning 'while', and then it's to be followed by the statement to partake in the loop until the condition is met as well as to increment value in the loop.
Example :
i = 1;
while(i<=10)
{
s = s + i;
p = p * i;
i++;
}
But, in case of summing of odd numbers program no such incrementing value has been shown.
And, strangely enough(for me), I get correct result w/o the use of i++. I absolutely cannot wrap my head around why that is the case. Is mentioning i++ or i+1 not really a rule within loops?
int s, i, n;
s = 0;
i = 1;
while (i <= n)
{
s = s + i;
i = i + 2;
}
This line is the incrementing value:
i = i + 2;
The first loop increments by 1 with i++. But since you only want the odd numbers, you need to increment by 2.
You can simplify this to:
i += 2;
There is no such rule that we must use i++ in every loop(and for that matter using i as a loop variable).
As #Barmar indicated, you are incrementing i using the line :
i = i + 2;
There are cases where we need to increment by 3, 10, √n, logn, etc.
There are even cases where we need to run a loop backwards hence, we decrement i.
The point is, the value of i must change at some point otherwise we'll end up in an infinite loop.
The task is to ask user from which character and till where he wants to create another string.
int main()
{
char a[]="Working with stirng is fun";
printf("%s",a);
int s,e,j=0;
scanf("%d%d",&s,&e);
char b[e-s+2];
for(int i=s-1;i<=e-1;i++){
a[j]=b[i];
j++;
}
a[j]='\0';
printf("%s",b);
}
for eg: if the user enters 4 and 7, the output should be "king".
You appear to be trying to copy a portion of a to b, but in fact are assigning to elements of a.
You have your assignment in the loop backwards. Your a[] variable is the source string and b[] is the destination, but your assignment is a[j]=b[i]; which assigns b[i] to a[j]. This is a Really Good Example, by the way, of why variable names like a and b are bad. Had you used variable names like big_string and sub_string you wouldn't have had this problem. Similarly, names like i and j when you have multiple strings are confusing--big_index and sub_index or some such would be far more clear.
Stylistically, you would do better to keep i and j more closely parallel, instead of declaring and increment i on the for line, and declaring and incrementing j entirely differently:
int i, j;
for (i = s - 1, j = 0 ; i <= e - 1 ; i++, j++)
b[j] = a[i];
b[j] = '\0';
seems much cleaner to me.
Better yet, in my opinion, would be to use a single variable to track the number of chars processed, and use it as an offset to the original string and the index to the substring:
start--; // adjust user's input to start at 0 instead of 1
end--;
int dex;
for (dex = 0 ; dex <= end - start ; dex++)
sub_string[dex] = orig_string[start + dex];
sub_string[dex] = '\0';
(I also changed to more clear variable names, and shifted the correction for indexing from 1 to 0 to the variables instead of doing math inside the loop which just adds confusion).
And finally, the easiest way of all to do this is to use the built-in strncpy() function:
strncpy(sub_string, &orig_string[start], end - start + 1);
Just change the line
a[i] = b[j];
to b[j]=a[i];
and a[i] = '\0';
to b[j]='\0';
I want to initialise an array in C following a pattern.
For example, here are two arrays with 10 elements. Each array have following elements: {0,0,2,3,0,7,0,1,9,0}
And here is my code: Note: example above and code below are not related, just to elaborate the definition of "pattern" in my case.
void CreateArray()
{
int i = ArraySize();
int j;
int k = Rand_Gen();
printf("%d\n",i);
int array[i];
for (j=0;j<i;j++)
{
if (k>0 && k<=30)
{
array[j]=4;
array[j+2]=23;
array[j+5]=900;
printf("%d",array[j]);
}
else if (k>30 && k<=60)
{
array[j]=2;
array[j+3]=54;
array[j+5]=870;
printf("%d",array[j]);
}
else
{
array[j]=0;
printf("%d",array[j]);
}
}
}
However, after running this program, I can only get an array with the same element. In this case, half of the time I get an array filled with 4 only, and half of the time I get 2.
I have done Googling but I could not find a possible solution to my problem. Or, maybe my method to print elements of the array is not correct?
Thanks first.
Follow up:
I have tried adding "int k = Rand_Gen()" within loop, but I still can only get one number. Here is the update segment of code:
void CreateArray()
{
int i = ArraySize();
int j;
printf("%d\n",i);
int array[i];
for (j=0;j<i;j++)
{
int k = Rand_Gen();
//some if statements here.
}
}
You use :
int k = Rand_Gen();
outside your for loop. This means that k will only be created once. Consequently, your for loop will be executed i times with the same value of k and therefore it will be entering the same part of your if-else statement. You need to generate k inside your loop.
Another issue is that your index 'j' gets out of your array bounds. In particular, your loop runs as following :
for (j=0;j<i;j++)
At some point, j will reach value i-1 (which will be the last iteration). At this point, your if and your else if parts try to access the positions array[j+2], array[j+3] and array[j+5].
However, you have declared array to be of size i so the statements :
array[j+2] = ... ;
array[j+3] = ... ;
array[j+5] = ... ;
with j being i-1 will be equivalent to :
array[i+1] = ... ;
array[i+2] = ... ;
array[i+4] = ... ;
which is definetely indexing out of bounds.
Move k = Rand_Gen(); inside for loop.
Currently you are generating 'k' value only once.
Also accessing j+2 index make out of bound access.
I know a while loop can do anything a for loop can, but can a for loop do anything a while loop can?
Please provide an example.
Yes, easily.
while (cond) S;
for(;cond;) S;
The while loop and the classical for loop are interchangable:
for (initializer; loop-test; counting-expression) {
…
}
initializer
while (loop-test) {
…
counting-expression
}
If you have a fixed bound and step and do not allow modification of the loop variable in the loop's body, then for loops correspond to primitive recursive functions.
From a theoretical viewpoint these are weaker than general while loops, for example you can't compute the Ackermann function only with such for loops.
If you can provide an upper bound for the condition in a while loop to become true you can convert it to a for loop. This shows that in a practical sense there is no difference, as you can easily provide an astronomically high bound, say longer than the life of the universe.
Using C
The basic premise is of the question is that while loop can be rewritten as a for loop. Such as
init;
while (conditional) {
statement;
modify;
}
Being rewritten as;
for ( init; conditional; modify ) {
statements;
}
The question is predicated on the init and modify statements being moved into the for loop, and the for loop not merely being,
init;
for (; conditional; ) {
modify;
}
But, it's a trick question. That's untrue because of internal flow control which statements; can include. From C Programming: A Modern Approach, 2nd Edition you can see an example on Page 119,
n = 0;
sum = 0;
while ( n < 10 ) {
scanf("%d", &i);
if ( i == 0 )
continue;
sum += i;
n++;
}
This can not be rewritten as a for loop like,
sum = 0;
for (n = 0; n < 10; n++ ) {
scanf("%d", &i);
if ( i == 0 )
continue;
sum += i;
}
Why because "when i is equal to 0, the original loop doesn't increment n but the new loop does.
And that essentially boils down to the catch,
Explicit flow control inside the while loop permits execution that a for loop (with internal init; and modify; statements) can not recreate.
While loops can be more helpful when the number of loop iterations are not known while for loops are effective when the loop iterations are known.
Consider the following code snippet for student marks, but the number of students is not known
ArrayList studentMarks = new ArrayList();
int score = 100;
int arraySize = 0;
int total = 0;
System.out.println("Enter student marks, when done press any number less than 0 0r greater than 100 to terminate entrancies\n");
while(score >= 0 && score < 101) {
System.out.print("Enter mark : ");
score = scan.nextInt();
if(score < 0 | score > 100)
break;
studentMarks.add(score);
arraySize += 1;
}
// calculating total, average, maximum and the minimum values
for(int i=0;i<studentMarks.size();i++) {
total += studentMarks.get(i);
System.out.println("Element at [" + (i+1)+"] : " +studentMarks.get(i));
}
System.out.println("Sum of list element is : " + total);
System.out.println("The average of the array list : " + (total/(studentMarks.size())));
Collections.sort(studentMarks);
System.out.println("The minimum of the element in the list is : " + studentMarks.get(0));
System.out.println("The maximum of the element in the list is : " + studentMarks.get(studentMarks.size()-1));
scan.close();
While loop does not have as much flexibility as a for loop has and for loops are more readable than while loops. I would demonstrate my point with an example. A for loop can have form as:
for(int i = 0, j = 0; i <= 10; i++, j++){
// Perform your operations here.
}
A while loop cannot be used like the above for loop and today most modern languages allow a for each loop as well.
In my opinion, I could be biased please forgive for that, one should not use while loop as long as it is possible to write the same code with for loop.
In C-like languages, you can declare for loops such as this:
for(; true;)
{
if(someCondition)
break;
}
In languages where for is more strict, infinite loops would be a case requiring a while loop.