Why in this JUnit test it shows wrong number? - java

So here is my solution code:
public int count_two_char(String s, char c, char d){
int count = 0;
int count1 = 0;
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == c) {
count = count + 1;
}
for (int i1 = 0; i1 < s.length(); i1++) {
if (s.charAt(i1) == d) {
count1 = count1 + 1;
}
}
}
return count + count1;
}
And here is my test code:
#Test
public void tests3() {
code.Solution s = new code.Solution();
String input = "llss";
int expected = 4;
char c ='l';
char d ='s';
int actual = s.count_two_char(input, c, d);
assertTrue("Expected was" +expected+"but the actual was" +actual , expected == actual);
}
But when I test it. It shows a error which is expected was 4 but the actual was 10. why?? I'm so confuse right now.

Because your braces aren't indented well, it appears that you have 2 separate for loops. But after lining them up better:
for(int i=0; i<s.length(); i++){
if(s.charAt(i) == c){
count = count + 1;
}
for(int i1=0; i1<s.length(); i1++){
if(s.charAt(i1) == d){
count1 = count1 + 1;
}
}
}
You can see that the second for loop is nested inside the first for loop, so your count1 will be higher than expected.
Move that last brace between the for loops and they will be unnested. That should reduce the count returned so that your test passes.

This is because you have a for loop that you do not need. Both ifs should go into the same loop, like this:
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == c) {
count = count + 1;
}
if (s.charAt(i) == d) {
count1 = count1 + 1;
}
}
As it stands, the number of d characters is multiplied by the length of the string, producing 2+4*2=10.
You can make your code more idiomatic to the language if you replace count = count+1 with the equivalent count++. You could also drop count1 altogether, because you add the two counts at the end anyway.

Related

Recursive 2D 5x5 counting 'a' function in java

I have to write a method that returns the count of 'a' chars in the matrix but I have to do it with using recursion and it must be O(n.log(n)).
This is the my non-recursive code:
public static int acount(char[][] mat) {
int result = 0;
int i = 0;
int j = 0;
while (i <= 4) {
if (mat[i][j] == 'a') {
result++;
j++;
}
if (mat[i][j] == 'b') {
i++;
j = 0;
}
}
return result;
}
This is what i have tried but there was an error: "Exception in thread "main" java.lang.StackOverflowError":
public static int acount(char[][] mat) {
int result = 0;
int i = 0;
int j = 0;
while (mat[i][j] == 'a') {
result++;
j++;
}
if (i < 5) {
i++;
j = 0;
} else {
return result;
}
return acount(mat);
}
This is the main code:
public static void main(String[] args) {
int n = 5;
Random rand = new Random();
char[][] input = new char[n][n];
for (int i = 0; i < n; i++) {
int a_num = rand.nextInt(n);
for (int j = 0; j < a_num; j++) {
input[i][j] = 'a';
}
for (int j = a_num; j < n; j++) {
input[i][j] = 'b';
}
}
System.out.println(Arrays.deepToString(input));
System.out.println(acount(input));
}
}
How can it resolved?
Okay, let's start with your original version.
public static int acount(char[][] mat) {
int result = 0;
int i = 0;
int j = 0;
while (i <= 4) {
if (mat[i][j] == 'a') {
result++;
j++;
}
if (mat[i][j] == 'b') {
i++;
j = 0;
}
}
return result;
}
This code looks problematic. First, it assumes that your input only contains a or b. If you include other data, you'll never increment either i or j and you loop forever. It also looks like you're assuming that each row in the matrix is a-a-b-who-cares. That is, all a's, but you stop looking at the first b. Is that what you really want? Maybe it is.
I would have written this as:
for (int index1 = 0; index1 < 5; ++index1) {
for (int index2 = 0; index2 < 5; ++index2) {
if (mat[index1][index2] == 'a') {
++result;
}
}
}
And actually, i wouldn't hard-code 5 but would instead use mat.length and mat[index1].length respectively.
As for your stack overflow -- this is because your recursion never ends. You do this:
return acount(mat);
That is, you call acount with the same array again, which calls acount again, which calls acount again...
The only way that doesn't fail is if your code above returns early, which it probably won't. I think what you're missing is that each time you enter acount, you get fresh variables, so i and j start out freshly as zeros again.
You could partially solve this by passing i into acount, and when you recurse:
return acount(mat, i+1);
That will fix some of the problem, although I think you're complexity is still O(n^2).
Then let's look at this:
while (mat[i][j] == 'a') {
result++;
j++;
}
What happens if the row never has any a's in it? It looks past the end of the array. You're making assumptions about the input data, which is going to bite you.

Java CARD Class compare method

int[] value = new int[5];
boolean result = true;
for(int i = 0; i < 5; i++) {
value[i] = cards[i].getValue();
}
for(int i = 0; i < 5; i++) {
for(int j = i;j < 5; j++) {
if(value[i] == value[j + 1]) {
result = false;
}
}
}
return result;
This code is essentially going to compare the values each card object has, and if two cards in the array have the same value return true. We have 5 cards in each hand and that is why the array length is 5. The getValue method returns an integer which is essentially the value of the card. I don't seem to know what I'm doing wrong to be getting errors on my method.
Your array access is incorrect when you use j + 1, that will be out of bounds when j is four (at the end of the length for value). And, I would prefer to use value.length instead of hardcoding. Something like
for (int i = 0; i < value.length - 1; i++) {
for (int j = i + 1; j < value.length; j++) {
if (value[i] == value[j]) {
result = false;
}
}
}
Additionally, as pointed out by Tom, in the comments; it is pointless to continue iteration when the result becomes false. You could simply return when it becomes false and avoid the result variable entirely. Like,
for (int i = 0; i < value.length - 1; i++) {
for (int j = i + 1; j < value.length; j++) {
if (value[i] == value[j]) {
return false;
}
}
}
return true;
Another option, in Java 8+, would be something like
return IntStream.of(value).allMatch(x -> value[0] == x);

How can I simplify boolean Algebra Expressions without using outside Java addons?

I am trying to take a Boolean algebra expression generated from another part of the project and simplify it before I output it. This Boolean expression will only include or statements due to the nature of the rest of the program.
An example would be starting with an expression like aC + bC + BC + Ab + Ac + AC + AB and ending with A + C. The lower case letters indicate not e.g. a means not A.
I have struggled for hours trying to figure this out, but every time I solve one case I ruin another. I imagine there is some recursive function for this problem but I struggled to find anything elsewhere.
Edit: To be clear, I understand how to simplify the expression on paper, I just am unable to simplify it using Java.
Thanks in advance.
public static void mutate (ArrayList<String> Final, ArrayList<String> Factored, String a){
int multiples = 0;
String holder = "";
for (int i = 0; i < Final.size(); i++){
if (Final.get(i).contains(a)){
multiples++;
if (multiples == 1)
holder = Final.get(i);
if (multiples >=2)
Factored.add(Final.get(i));
}
}
if (multiples > 1)
Factored.add(holder);
}
public static void simplify (ArrayList<String> Factored, char a, ArrayList<String> Main){
String temp = "";
int size = Factored.size();
int cnt = 0;
int cnt2 = 0;
int holder = 0;
System.out.println(Factored);
int menial = 0;
if (Factored.size() == 0)
menial = 1;
else{
for (int i = 0; i < size; i++){ //Gets rid of leading letters
if(Factored.get(i).charAt(0) == a){
temp = Factored.get(i).substring(1);
Factored.add(temp);
}
}
for (int i = 0; i < size; i++){ //Gets rid of leading letters
if(Factored.get(i).charAt(1) == a){
temp = Factored.get(i).substring(1);
Factored.add(temp);
}
}
for (int j = 0; j < size; j++){
Factored.remove(j - cnt);
cnt++;
}
for (int i = 0; i < Factored.size(); i++){ //gets rid of duplicates if they exist
for (int j = i + 1; j < Factored.size();j++)
if (Factored.get(i).equals(Factored.get(j))){
cnt2++;
if (cnt2 == 1)
holder = i;
}
}
if (cnt2 >= 1)
Factored.remove(holder);
String temp1 = "";
int size1 = Factored.size();
for (int i = 0; i < size1; i++){ //Makes it uppercase
temp1 = Factored.get(i).toUpperCase();
Factored.add(temp1);
}
int cnt3 = 0;
for (int i = 0; i <size1; i++){
Factored.remove(i-cnt3);
cnt3++;
}
int sizeOver2 = Factored.size()/2;
int holder1 = 0; int holder2 = 0;
for (int q = 0; q < sizeOver2; q++){
int cnt4 = 0;
for (int i = 0; i < Factored.size(); i++){ //gets rid of duplicates if they exist now that there are caps
for (int j = i + 1; j < Factored.size();j++)
if (Factored.get(i).equals(Factored.get(j))){
cnt4++;
if (cnt4 == 1)
holder1 = i;
holder2 = j;
}
if (cnt4 >= 1){
Factored.remove(holder1);
Factored.remove(holder2 - 1);
}
}
}
if (Factored.size() == 0)
Main.add(Character.toString(a));
else if (Factored.size() > 1)
menial = 5;
else
for (int i = 0; i < Factored.size(); i++)
Main.add(Factored.get(i));
}}
}
Edit2: I have added my code above. I apologize for the slopiness in advance, it got pretty messy towards the end. The Factored arraylist has all of the elements of the boolean expression separated E.g. the first element is aC, and the second is bC, etc. My plan was to find duplicates and try to factor them out, but after coding all of this I realized the egregious logic error. It has to be more complicated than that and at this point I'm lost in my own code.

Can you give me idea on how to code this program using array and for loops?

I was supposed to make a program using for loop and arrays now the output program will need to show something like this
0-1-0-0-1-0-0-0-1-0-0-0-0-1
Notice that the 0 is adding every after the 1's show so far im stuck with this code can you help me please...
int[] binary = new int[150];
int b = 0;
int x = 3;
for(int a = 0; a < binary.length; a=a+2) {
box[a] =1;
}
for(int i =0; i < binary.length; i++){
for(b = 0; b < binary.length; b = b+x){
if(box[b] == 1) {
box[b] =0; // this condition changes the value of 1 to 0 if the binary is already "1".
}
else {
box[b] =1; // if the value of the binary is 0 it changes it to 1.
}
}
x++; // Putting this changes the value of the x making x=4 so that the next time the for loop runs it adds the int b to 4..(NOT SURE IF THIS IS RIGHT THOUGH)
}
for(int c =0; c < binary.length; c++) {
System.out.print(binary[c]); // "this should print the output "
}
My problem is making it show something like this
01001000100001000001
You're mixing multiple variable names, since you assign the values to box you should probably remove binary - so something like,
int[] box = new int[150];
int b = 0;
int x = 3;
for (int a = 0; a < box.length; a = a + 2) {
box[a] = 1;
}
for (int i = 0; i < box.length; i++) {
for (b = 0; b < box.length; b = b + x) {
if (box[b] == 1) {
box[b] = 0;
} else {
box[b] = 1;
}
}
x++;
}
for (int c = 0; c < box.length; c++) {
System.out.print(box[c]); // "this should print the output "
}
Output is
101101111011111101111111101111111111011111111111101111111111111101111111111111111011111111111111111101111111111111111111101111111111111111111111011111
I'm not sure to fully understand what you want. From your post I only understand that your goal is to have an output composed of 0 and 1 only and starting with a 0 immediately followed by a 1. The number of zeros following a 1 is successively increased by 1 : so you have after that 2 zeros followed by a 1 and then 3 zeros followed by a 1, 4 zeros followed by a 1 and so one : 0-1-00-1-000-1-0000-1.
Am I right ?
If that is what you want, try something like that :
int num_zero = 1;
int cptr = 0;
int[] arr = new int[20];
for(int j = 0; j < arr.length; j++){
if(cptr == num_zero){
arr[j] = 1;
num_zero = 1+ cptr;
cptr = 0;
}else{
arr[j] = 0;
++cptr;
}
}
Here is the output :
01001000100001000001
Try this:
int[] binary = new int[150];
int onesNextIndex = 1;
int onesGap = 2;
for(int i = 0; i < binary.length; i++){
if(i == onesNextIndex){
binary[i] = 1;
onesNextIndex += onesGap + 1;
onesGap++;
}else{
binary[i] = 0;
}
}
You can test it with:
for(int x : binary){
System.out.print(x);
}
it will print: 0100100010000100000100000010000000100000000..... etc
if you want it the other way around then :
int[] binary = new int[150];
int zerosNextIndex = 1;
int zerosGap = 2;
for(int i = 0; i < binary.length; i++){
if(i == zerosNextIndex){
binary[i] = 0;
zerosNextIndex += zerosGap + 1;
onesGap++;
}else{
binary[i] = 1;
}
}
this will print: 101101110111101111101111110111111101111111101111.......etc
Hope this helps

Nested For loops to print numbers 11223344556677889900

I am trying to print the sequence of numbers 11223344556677889900 using nested for loops. I am unsure of the algorithm to print the sequence since it ends in 00. I have the following method code but I print the 00 as literals and am sure that there must be a better way. Any help is much appreciated.
public static void drawNumbers(){
for (int line = 1; line <= 2; line++) {
for (int i =1; i <= 9; i++) {
for (int j =1; j<=2; j++) {
System.out.print(i);
}
}
System.out.print("00");
}
}
Run your loop up to 10 and instead of:
System.out.print(i);
do:
System.out.print(i % 10);
public static void drawNumbers(){
for (int line = 1; line <= 2; line++){
for (int i =1; i <= 10; i++){
for (int j =1; j<=2; j++){
System.out.print(i%10);
}
}
}
}
You can run the "i" loop until 10 and print i%10. This would print 0 when the value reaches 10.
One other way would be to insert an if statement inside the for where you would check if the value of i was equal to "10", and if it were, it would print the value "00"
Just only print the last digit of i
for (int i = 1; i <= 10; i++) {
String s = String.valueOf(i);
int lastDigit = s.length() - 1; // last digit position in string
System.out.print(s.substring(lastDigit, lastDigit + 1)); // print last digit
System.out.print(s.substring(lastDigit, lastDigit + 1)); // print last digit
}
Output:
11223344556677889900
Changed the logic a little to fit your requirement
public static void drawNumbers() {
for (int line = 1; line <= 1; line++) {
for (int i =1; i <= 10; i++) {
for (int j =1; j<=2; j++) {
if(i==10) {
System.out.print(0);
} else {
System.out.print(i);
}
}
}
}
}
To use only one loop run it like
public static void drawNumbers() {
for(int i = 1 ;i <= 10; i++) {
if(i ==10) {
System.out.print(0 + "" + 0);
} else {
System.out.print(i + "" + i);
}
}
}

Categories

Resources