Java cannot find symbol for loops, logic problems? - java

Ok, my program in this specific section takes a line of data from a studentAnswer string array, the value of which would be something like TTFFTFTFTF. I am supposed to take this, and compare it against a key array, which might look like TFFFTFTFTF. A student takes a quiz, and my program calculates the points correct.
My intention is to use a separate points array to find the numeric grade for the student. The index of studentAnswer refers to a specific student. So studentAnswer[i] is TTFFTFTFTF. I use substrings to compare each individual T/F against the correct answer in key[], which would have a single T/F in each index. Then, if they are correct in their answer, I add a 1 to the correlating index in points[] and will later find the sum of points[] to find the numeric grade out of ten.
My problem here is that String origAns, used to define the student's original answer string, is getting a Java Error cannot find Symbol. I have tried placing the instantiation of origAns within each different for loop, but I can't get the program to work. Int i is meant to follow each specific student- I have four parallel arrays that will all log the student's ID number, numeric grade, letter grade, and original answers. So that is the intention of i, to go through each student. Then j should be used to go through each of these original student answer strings and compare it to the correct answer...
Logically, it makes sense to me where I would put it, but java doesn't agree. Please help me to understand this error!
for (int i = 0; i < studentAnswer.length; i++){
String origAns = studentAnswer[i];
for (int j = 0; j < key.length; j++){
if (origAns.substring[j] == key[j]){
//substring of index checked against same index of key
points[j] = 1;
}
if (origAns.substring[j] != key[j]){
points[j] = 0;
}
}
}

It sounds like you're trying to call the substring method - but you're trying to access it as if it were a field. So first change would be:
if (origAns.substring(j) == key[j])
Except that will be comparing string references instead of contents, so you might want:
if (origAns.substring(j).equals(key[j]))
Actually, I suspect you want charAt to get a single character - substring will return you a string with everything after the specified index:
if (origAns.charAt(j) == key[j])
... where key would be a char[] here.
You can also avoid doing the "opposite" comparison by using an else clause instead.
You should also indent your code more carefully, for readability. For example:
for (int i = 0; i < studentAnswer.length; i++) {
String origAns = studentAnswer[i];
for (int j = 0; j < key.length; j++) {
if (origAns.charAt(j) == key[j]) {
points[j] = 1;
} else {
points[j] = 0;
}
}
}
And now, you can change that to use a conditional expression instead of an if/else:
for (int i = 0; i < studentAnswer.length; i++) {
String origAns = studentAnswer[i];
for (int j = 0; j < key.length; j++) {
points[j] = origAns.charAt(j) == key[j] ? 1 : 0;
}
}

When you call a method in Java, you use parentheses () instead of brackets [].
Since substring is a method, you should call it like so
if (origAns.substring(j) == key[j])
A few other notes, you should use the equals method for comparisons (especially those comparisons involving Strings.)
if (origAns.substring(j).equals(key[j]))
Also, you should use charAt to extract a single character at some position in a string. substring(j) will return a string of characters starting at position j.
if (origAns.charAt(j).equals(key[j]))

Your explanation is very long and I have not read it from the beginning to end. But I can see at least one problem in your code:
if (origAns.substring[j] == key[j])
You are comparing strings using == instead of using method equals():
if (origAns.substring[j].equals(key[j]))

Substring is a function, not a member, of String objects. Check out the example at the top of this page:
http://docs.oracle.com/javase/6/docs/api/java/lang/String.html
Notice the use of parenthesis instead of brackets.

If you are using a String use charAt function
String studentAnswer = "TTFFTFTFTF";
for (int i = 0; i < studentAnswer.length(); i++)
{
char origAns = studentAnswer.charAt(i);
}
Else if you are using an char array then
char studentAnswer[] = "TTFFTFTFTF".toCharArray();
for (int i = 0; i < studentAnswer.length; i++){
char origAns = studentAnswer[i];
}

Related

Finding number of sub strings between two giving chars

I need for my homework to write method that get two parameters, string and char, and it needs to return the number of strings that start with that char and end with that char.
Example:
For the string "abcbcabcacab" and the char 'c', the method will return 6.
(the sub strings are "cbc", "cabc", "cac", "cbcabc", "cabcac", "cbcabcac")
It needs to be as effectiveness as possible, and the only two method that I can use is charAt() and length().This is hard as hell and after 3 hours of trying, I'm asking you guys if there is someone who cal solve this or at least show me some clue.
The obvious solution is to check every symbol in input string and if equals to specified char, then try to find all possible substrings, starting from this point, like this:
long cnt = 0;
for (int i = 0; i < (s.length() - 1); i++)
if (s.charAt(i) == c)
for (int j = (i + 1); j < s.length(); j++)
if (s.charAt(j) == c)
cnt++;
return cnt;
this solution has complexity O(N^2)
but, number of substrings actually determined by number of occurrences of char in string, which appeared to be Triangular number
So, optimized O(N) solution is:
long cnt = -1;
for (int i = 0; i < s.length(); i++)
if (s.charAt(i) == c)
cnt++;
return (cnt * (cnt + 1)) >>> 1;
The simplest anwser is that you should use a loop.
Loop through the strings. Check if the current string starts with the given char and ends with the given char. If it doesn't just jump to the next one. if it does just loop with a counter from 1 to length minus the second last char.
You will reduce time by kicking out invalid string and you will be checking 2 chars less EVERY string ;)
I guess that's a quite fast way.
Example
// String definition bla String[] myArray
int count = 0;
for(int i = 0; i < myArray.length(); i++) {
if(myArray[i].charAt(0) == givenChar && myArray[i].charAt(myArray.length()-1)) {
for(int j = 1; j < myArray.length()-2;j++) {
if(myArray[i].charAt(j) == givenChar)
count ++;
}
}
}
That's the rough idea.
I am checking if the given String starts and ends with the givenChar.
If it does im iterating through the string checking for the givenChar again.
If it does exist i am counting 1 up.
I hope that might help your out ;)
Have a nice day!

How to find first instance of element array

I'm a pretty basic programmer and I'm coding a 'Master-mind' style guessing game program.
Now the part I'm stuck with is that I want to go through an array and increase the pointer when I come across a specific number.
Now thats pretty easy and stuff, but what I want to do is ONLY increase the counter if the number is encountered for the first time. So, for example if there are two numbers (189, 999), I want the counter to increase only once, instead of 3 times, which is what my code is doing. I know why its doing that, but I can't really figure out a way to NOT do it (except maybe declaring an array and putting all the repeated numbers in there and only incrementing it if none of the numbers match, but that's super inefficient) Here's my code:
for (int i = 0; i < mString.length(); i++) {
for (int j = 0; j < nString.length(); j++) {
if (mString.charAt(i) == nString.charAt(j)) {
correctNumbers++;
}
}
}
Thanks for taking the time to read! I'd prefer it if you wouldn't give me a direct answer and just point me in the right direction so I can learn better. Thanks again!
Your question is quite unclear. I suppose 989 and 999 will return 1. Because you only deal with number, so the solution is:
Create a boolean array with 9 element, from 0-9, named isChecked
Initialize it with false.
Whenever you found a matching number, say 9, turn the boolean element to true, so that you don't count it again (isChecked[9] = true).
Here is the code:
var isChecked = [];
function resetArray(input) {
for (var i = 0; i < 10; i++) {
input[i + ''] = false;
}
}
resetArray(isChecked);
var firstNumber = '989',
secondNumber = '999',
correctNumbers = 0,
fNum, sNum;
for (var i = 0; i < firstNumber.length; i++) {
fNum = firstNumber.charAt(i);
// Skip already checked numbers
if (isChecked[fNum]) {
continue;
}
for (var j = 0; j < secondNumber.length; j++) {
sNum = secondNumber.charAt(j);
if (fNum == sNum && !isChecked[sNum]) {
correctNumbers++;
isChecked[sNum] = true;
}
}
}
console.log(correctNumbers);
Tested on JSFiddle.
If you find anything unclear, feel free to ask me :)
(except maybe declaring an array and putting all the repeated numbers in there and only incrementing it if none of the numbers match, but that's super inefficient)
That approach is a good one, and can be made efficient by using a HashSet of Integers. Everytime you encounter a common digit, you do a contains on the set to check for that digit (gets in HashSets are of constant-time complexitiy - O(1), i.e. super quick), and if it's present in there already, you skip it. If not, you add it into the set, and increment your correctNumbers.
I believe this would help
int found=0; for (int i = 0; i < mString.length(); i++) {
for (int j = 0; j < nString.length(); j++) {
if (mString.charAt(i) == nString.charAt(j)) {
if(found==0){
correctNumbers++;
}
}
}
}
You could try making another 1D array of
int size = nstring.length() * mstring.length();
bool[] array = new bool[size];`
and then have that store a boolean flag of whether that cell has been updated before.
you would find the unique index of the cell by using
bool flag = false
flag = array[(i % mString.length()) + j)];
if(flag == true){
<don't increment>
}else{
<increment>
array[(i % mString.length()) + j)] = true;
}
you could also do this using a 2d array that basically would act as a mirror of your existing table:
bool[][] array = new bool[mstring.length()][nString.length()];
Why not just use the new stream api? Then it's just that:
Arrays.stream(mString).flatMapToInt(s -> s.chars()).distinct().count();
I'll explain:
Arrays.stream(mString) -> Create stream of all strings.
flatMapToInt -> create single concatenated stream from many IntStreams
s -> s.chars() -> Used above to create streams of characters (as ints)
distinct -> remove all duplicates, so each character is counted only once
count -> count the (unique) characters

Avoiding duplicates without Sets?

I am in a beginner Java class and I haven't gotten the chance to learn how to avoid duplicated values when storing values inside arrays.
String[] newAlphabet = new String[26];
for(int I = 0; I < newAlphabet.length; I++){
int random = (65 + (int)(Math.random() * ((90 - 65) + 1));
char ascii = (char)random;
String letters = ascii + "";
if(letters != newAlphabet[0] && letters != newAlphabet[1] ... so on and so on until
newAlphabet[25])
newAlphabet[I] = letters;
}//end
So this is my pseudo code for part of my program and the point of it is to avoid having duplicated letters inside the array.
The problem that I am having is inside the if statement. Instead of typing letters != newAlphabet[] to 25, is there another way of doing it?
I have seen some of the forums in stackedoverflow that I should use HashSet but I have not learned that? I can ask my teacher if I am allowed but is there another way to avoid this problem?
I have been thinking of using for-each loop to search through all the elements in the array but I haven't thought out the plan long enough if it's valid.
As you are talking about a beginner Java class, I am assuming you are fairly new to programming. So, rather than just give you a library function that will do it for you, let's walk through the steps of how to do this with just the basic code so you can get a better idea of what is going on behind the scenes.
Firstly, for any repetitive action, think loops. You want to check, for each letter in your new alphabet, if the one you are about to add matches it. So...
boolean exists = false; //indicates whether we have found a match
for (int j = 0; j < 26; j++) { //for each letter in the new alphabet
//true if this one, or a previous one is a match
exists = exists || letters == newAlphabet[i];
}
//if we don't have a match, add the new letter
if (!exists) newAlphabet[I] = letters;
Now, as you are building up your new alphabet as we go, we don't have a full 26 letters for most cases of running this code, so only check the parts of the new alphabet we have defined:
boolean exists = false;
for (int j = 0; j < I; j++) { //note in this line we stop before the insertion point
exists = exists || letters == newAlphabet[i];
}
if (!exists) newAlphabet[I] = letters;
Finally, we don't need to keep checking if we have already found a match, so we can change the loop to stop when we have found a match:
boolean exists = false;
int j = 0;
while (!exists && j < I) { //we now also stop if we have already found a match
exists = letters == newAlphabet[i];
//as we are stopping at the first match,
//we no longer need to allow for previous matches
}
if (!exists) newAlphabet[I] = letters;
You could use the asList method:
if( Arrays.asList(newAlphabet).contains(letters) ) {
newAlphabet[I] = letters;
}
It's not the most efficient, but since your array is only 26 elements long, I would favor clarity over efficiency.
Some explanation: asList is a static method on the Arrays class. This just means that we don't have to create an Arrays object to call it. We simply say Arrays.asList() and pass it the arguments. The asList method takes an array (newAlhpabet in this case) as a parameter, and builds a java.util.List out of it. This means that we can call List methods on the return value. contains() is a method on List that returns true if the List contains an element that is equal to the parameter (letters in this case).
Based on this line it looks like all you're trying to do is produce the letters A to Z in some other order:
int random = (65 + (int)(Math.random() * ((90 - 65) + 1));
If I'm understanding that right, then really all you're trying to do is shuffle the alphabet:
// Initialize new alphabet array
String originalAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char[] newAlphabet = originalAlphabet.toCharArray();
// Shuffle the new alphabet by swapping each character to a random position
for (int i=0; i<26; i++) {
int j = (int)(Math.random() * 26);
char temp = newAlphabet[i];
newAlphabet[i] = newAlphabet[j];
newAlphabet[j] = temp;
}
// Print the new alphabet
for (int i=0; i<26; i++) {
System.out.print(newAlphabet[i]);
}
System.out.println();
Here's a sample output: VYMTBIPWHKZNGUCDLRAQFSOEJX
You have a couple options.
Loop through the array and do basically what you're doing now.
Insert the characters in sorted order so you can perform binary search to determine if a letter is already in the list. As a bonus, if you use option 2, you'll already know the insertion point.
Check out Arrays.binarySearch(): http://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html
You could use this :
if(Arrays.binarySearch(newAlphabet, letters) < 0){
newAlphabet[I] = letters;
}
You should either include a while loop to make sure each index of the array is filled before moving to the next or you could make use of the return value of Arrays.binarySearch which is (-(insertion index) - 1) to fill the array and exit when the array is filled up.

java.lang.ArrayIndexOutOfBoundsException error in java

So basically, I've created a contains method and it prints out the correct output I need but after it does this it gives me an error:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at MethodTesting.main(MethodTesting.java:90)
Not sure why when it displays the output no worries? If anyone can give me an idea of what i'm doing wrong?? My code is below, i've tried adjusting the length to just length and length-1 as seen below. I've written the code in strings as opposed to char arrays however it wouldn't give me the right result. Hoping someone can shed some light perhaps?
//contains method
char[] st = "Hello World".toCharArray();
char[] substr = "llo".toCharArray();
for(int contains=0; contains<st.length-1; contains++){
if(substr[contains] == st[contains]){
for(int j=contains; j<st.length-1; j++){
if(st[j] == substr[j]){
}
else{
contains = -1;
}
}
}
System.out.println("CONTAINS");
System.out.println(contains);
}
Thanks, in advance!
Assuming that you are trying to search a substring of a string, this can be done in String.contains() method. If you are trying to implement the method yourself, then you have to change your code like this:
public static void main (String[] args)
{
char[] st = "Hello World".toCharArray();
char[] substr = "llo".toCharArray();
for(int contains = 0; contains < st.length - substr.length; contains++) {
int j;
for(j = 0; j < substr.length; j++) {
if(st[contains + j] != substr[j]) { // mismatch
break;
}
}
if (j == substr.length) // Every character in substr has been matched
System.out.println("Contains");
}
}
Your arrays aren't of equal length, yet in your second loop, you make an assumption that they are. contains can be a value higher than substr.length, and consequently, j will be, too.
To ensure that you don't step off the array while iterating, fix your bounds in your second loop.
Change for(int j=contains; j<st.length-1; j++) to for(int j=contains; j<substr.length; j++). This will ensure that your second loop is never executed if contains > substr.length, whereas it was executing as long as j < st.length()-1.
st array length and substr lengths are different.So the line
j<st.length-1; should be j<substr.length-1;

String index out of range: n

Im having a bit of a problem with this code each time i execute it it gives me an error
String index out of range: 'n'
n - is the no. of characters that is entered in the textbox pertaining to this code...
(that is textbox - t2.)it is stuck at that first textbox checking it does not go over to the next as mentioned in the array.
Object c1[] = { t2.getText(), t3.getText(), t4.getText() };
String b;
String f;
int counter = 0;
int d;
for(int i =0;i<=2;i++)
{
b = c1[i].toString();
for(int j=0;j<=b.length();j++)
{
d = (int)b.charAt(j);
if((d<65 || d>90)||(d<97 || d>122))
{
counter++;
}
}
}
it is basically a validation code that i am trying to do without exceptions and stuff(still in the process of learning :) )
any help would be appreciated
thx very much.
Use <, not <= when iterating over the string. With <=, you get an out of bounds error, when j equals the length of the string. Remember that characters in the string are indexed starting from zero.
for(int j = 0; j < b.length(); j++)
In java string.charAt(string.length()) will be out of bounds since the string is 0 indexed and so the last character is at string.length() - 1.
Strings are indexed starting at 0. Your second for loop is set to end at b.length, which will always be 1 greater than the highest index for that string., Change it to j < b.length instead.

Categories

Resources