Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I'm trying to write for code that searches for the first occurrence of a string (a needle) within another string (a haystack) and return the index of the first character in the matching string.
I've found the following solution online, but I'm having trouble understanding how it works. Can someone please explain to me how it functions?
private static int strStr(String needle, String haystack)
{
for (int i=0;;i++) { //
for (int j=0;;j++) {
if (j== needle.length()) return i;
if (i + j == haystack.length()) return -1;
System.out.println("needle.charAt(j) "+j+" "+needle.charAt(j));
System.out.println("haystack.charAt(i+j) "+(i+j)+" "+haystack.charAt(i+j));
if (needle.charAt(j) != haystack.charAt(i + j)) break;
}
}
}
private static int strStr(String needle, String haystack)
{
for (int i = 0 ; ; i++)
{
for (int j = 0 ; ; j++)
{
if (j == needle.length())
{
return i;
}
if (i + j == haystack.length())
{
return -1;
}
System.out.println("needle.charAt(j) " + j + " " + needle.charAt(j));
System.out.println("haystack.charAt(i+j) " + (i + j) + " " + haystack.charAt(i+j));
if (needle.charAt(j) != haystack.charAt(i + j))
{
break;
}
}
}
}
First, let's establish a few things:
Java starts indices at 0, so needle.charAt(0) is the first character in the string. needle.charAt(3) is the fourth character in the string.
The line for(int i = 0 ; ; i++) increments i by one through each iteration, and the for-loop will not cause the loop to stop.
It's easiest to tackle this with an example. Let's use a needle named "hip" and a haystack named "chips". Since Java indices start at 0, we would expect that the method will return 1 (representing the second character), since that's the first character of "hip" within "chips".
When we enter the method, we go through the first for-loop. i = 0
The next line takes us into another for-loop. i = 0, j = 0
j = 0 does not equal needle.length() = 3
i + j = 0 + 0 = 0 does not equal haystack.length() = 5
needle.charAt(j = 0) is "h", haystack.charAt(i + j = 0 + 0 = 0) is "c". Since "h" is not equal to "c", we break out of the j-for-loop. The break keyword only breaks out of the current loop, so while we stopped executing the j for-loop, we're still within the i-for-loop.
We start the next iteration. i = 1
The j for-loop restarts at 0. i = 1, j = 0
j = 0 does not equal needle.length() = 3
i + j = 1 + 0 = 1 does not equal haystack.length() = 5
needle.charAt(j = 0) is "h", haystack.charAt(i + j = 1 + 0 = 1) is "h". Since these are equal, we don't break out of the j-for-loop.
We start the next iteration of the j for-loop. i = 1, j = 1
j = 1 does not equal needle.length() = 3
i + j = 1 + 1 = 2 does not equal haystack.length() = 5
needle.charAt(j = 1) is "i", haystack.charAt(i + j = 1 + 1 = 2) is "i". Since these are equal, we don't break out of the j-for-loop.
We start the next iteration of the j for-loop. i = 1, j = 2
j = 2 does not equal needle.length() = 3
i + j = 1 + 2 = 3 does not equal haystack.length() = 5
needle.charAt(j = 2) is "p", haystack.charAt(i + j = 1 + 2) is "p". Since these are equal, we don't break out of the j-for-loop.
We start the next iteration of the j for-loop. i = 1, j = 3
j = 3 does equal needle.length() = 3, so we return i = 1.
As we expected, we got 1 back from this function, since "hip" is contained within "chips" starting at position 1 (zero-indexed).
That's all well and good, but what about that i + j == haystack.length() line?
Let's use "ben" as the needle and "bear" as the haystack (we should get back -1, since "ben" does not appear in the word "bear").
/- needle.length()
| /- haystack.length()
| | /- needle.charAt(j)
| | | /- haystack.charAt(i + j)
| | | |
i | j |n.l|h.l|n.c|h.c| result
---+---+---+---+---+---+------------------
0 | 0 | 3 | 4 | b | b | continue
0 | 1 | 3 | 4 | e | e | continue
0 | 2 | 3 | 4 | n | a | break j
1 | 0 | 3 | 4 | b | e | break j
2 | 0 | 3 | 4 | b | a | break j
3 | 0 | 3 | 4 | b | r | break j
4 | 0 | 3 | 4 | | | i + j == haystack.length(), return -1
you can use contains() or indexOf() for that.
for example:
String str1 = "This is string of words";
String str2 = "string";
int pos = str1.indexOf(str2);
in pos will int with position. Also you can add toUpperCase(), in this case search will be without letter register.
Related
I have 2 variables A and B
if A =1 then B should B=2
and if A=2 then B should B=1
Like this, there are 3 pairs 1-2,3-4,5-6
What's the best way of making a code instead of just if-else
It is possible to use simple addition and subtraction to get the other element of the two (x, x + 1):
int a = 1; // the other is 2, sum is 3
int b = 3 - a; // if a = 2, b = 1
int c = 3; // the other is 4, sum is 7
int d = 7 - c; // if c = 4, d = 3
int m = 5; // the other is 6, sum is 11
int n = 11 - m;
Another approach could be using the following logic:
if (a % 2 == 1) b = a + 1;
else b = a - 1;
So, an array could be used to provide +/- 1:
static int[] signs = {-1, 1};
public static int nextWithArrPositive(int a) {
return a + signs [a % 2];
}
This expression fails to work for negative a as in this case a % 2 == -1 and more advanced logic would be required to calculate the value properly to take into account the negative remainder:
public static int nextWithArr(int a) {
int sign = (a & 0x80000000) >> 31; //-1 if a < 0, 0 otherwise
// a >= 0 : 0 - even, 1 - odd;
// a < 0 : 1 - even, 0 - odd
return a + signs[a % 2 - sign];
}
However, a simpler expression can be designed:
public static int nextWithMod(int a) {
return a + a % 2 - (a - 1) % 2;
}
Let's compare the results of the three implementations including xor solution b = ((a - 1) ^ 1) + 1 offered in the comments by user3386109:
public static int nextXor(int a) {
return ((a - 1) ^ 1) + 1;
}
Tests:
System.out.println("+-----+-----+-----+-----+");
System.out.println("| a | arr | mod | xor |");
System.out.println("+-----+-----+-----+-----+");
for (int i = -6; i < 7; i++) {
System.out.printf("| %2d | %2d | %2d | %2d |%n", i, nextWithArr(i), nextWithMod(i), nextXor(i));
}
System.out.println("+-----+-----+-----+-----+");
Output:
+-----+-----+-----+-----+
| a | arr | mod | xor |
+-----+-----+-----+-----+
| -6 | -5 | -5 | -7 |
| -5 | -6 | -6 | -4 |
| -4 | -3 | -3 | -5 |
| -3 | -4 | -4 | -2 |
| -2 | -1 | -1 | -3 |
| -1 | -2 | -2 | 0 |
| 0 | -1 | 1 | -1 |
| 1 | 2 | 2 | 2 |
| 2 | 1 | 1 | 1 |
| 3 | 4 | 4 | 4 |
| 4 | 3 | 3 | 3 |
| 5 | 6 | 6 | 6 |
| 6 | 5 | 5 | 5 |
+-----+-----+-----+-----+
One simple solution is a table lookup. In an array for each possible value of a I store the corresponding value of b:
private static final int[] B_PER_A = { -1, 2, 1, 4, 3, 6, 5 };
Since array indices always start at 0 in Java, we need to put a dummy value at index 0. This value is never used (or should never be, at least).
Let’s try it out:
for (int a = 1; a <= 6; a++) {
int b = B_PER_A[a];
System.out.format("a: %d; b: %d.%n", a, b);
}
Output:
a: 1; b: 2.
a: 2; b: 1.
a: 3; b: 4.
a: 4; b: 3.
a: 5; b: 6.
a: 6; b: 5.
Generalized to more than 3 pairs
If you need to handle a variable number of pairs, resort to math.
public static int calcB(int a) {
// 0-based index of pair (0 = 1-2, 1 = 3-4, etc.)
int pairNumber = (a - 1) / 2;
// a + b for given pair
int pairSum = 4 * pairNumber + 3;
int b = pairSum - a;
return b;
}
In each pair the sum is equivalent to 3 modulo 4. I am exploiting this fact in finding the sum for a given pair. When I subtract a from that sum, I get b. Let’s see that demonstrated too:
for (int a = 1; a <= 8; a++) {
int b = calcB(a);
System.out.format("a: %d; b: %d.%n", a, b);
}
a: 1; b: 2.
a: 2; b: 1.
a: 3; b: 4.
a: 4; b: 3.
a: 5; b: 6.
a: 6; b: 5.
a: 7; b: 8.
a: 8; b: 7.
The latter solution is more complicated and harder to read. So if you always have got three pairs, no more, no less, I recommend the simpler table lookup presented first.
I'm solving a challenge about making an algorithm.
There is a game of land.
The Land of Landing game consists of 4 rows in total N rows, with scores in all the columns.
When stepping down from the first row, down one row, you must step down on one of the four squares of each row.
However, there is a special rule that can not be repeated in the same row when landing one row at a time.
For example,
| 1 | 2 | 3 | 5 |
| 5 | 6 | 7 | 8 |
| 4 | 3 | 2 | 1 |
If you have stepped on line 1 through line 4 (5), you can not step on line 4 (8) on line 2.
I was trying to use Dynamic Programming in Java.
import java.lang.Math;
import java.util.*;
class Solution {
int [][] dp = new int[100001][4];
int solution(int[][] land) {
int r = land.length;
for (int i = 0; i < 4; i++)
{
dp[0][i] = land[0][i];
}
for (int i = 0; i <r; i++)
{
for (int j = 0; j < 4; ++j)
{
for(int k = 0; k < 4; ++k)
{
if (j != k)
{
dp[i][j] = Math.max(dp[i][j], land[i][j] + dp[i-1][k]);
}
}
}
}
int ans = 0;
for (int i = 0; i < 4; ++i)
{
ans = Math.max(ans, dp[r-1][i]);
}
return ans;
}
}
it shows error
java.lang.ArrayIndexOutOfBoundsException: -1
I was thinking that it was probably something wrong with the Conditional statement.
In C++, these conditional statements are right. It's running perfect. Why am I getting an error in Java? Is there any difference using array between Java and C++?
Can you please tell me how can I solve this error?
dp[i-1][k] - i starts from ZERO in upper loop, so results of this expression becomes -1 as index.
Java array index starts from ZERO, not -1, which is why ArrayIndexOutOfBoundsException.
I don't know the business case, but one way to solve this is, start first for loop from 1 instead 0.
I am working on a program that prints out a table filled with randomly-generated integers. Most of the logic is relatively straightforward and works pretty well. One thing I would like to do is to add up and print out total values for each column, as well as the final total of all the values in the table. I have searched around trying to find an answer but have had no luck with figuring it out.
rowNbr = 7; // ROW CONTROLS
colNbr = 5; //COLUMN CONTROLS
rpt01 = String.format("%0" + (colNbr-1) + "d", 0).replace("0",dash); //Redefine rpt01
colBld = String.format("|---------------|%s\n",rpt01); //Redefine colBld
String cnrTxt = "First Quarter";
System.out.printf(colBld);
System.out.printf("|%-15s",cnrTxt);
for(int i = 1; i < colNbr; i = i++){ //Open for loop (columns)
String regTxt = "Region " + i++;
System.out.printf("|%-10s",regTxt);
} //End for
System.out.printf("|\n");
//Initialize array
int sales[] = new int[100];
int idx = 0;
for(int i = 1; i <= rowNbr-3; i++){
String prodTxt = "Product " + i;
System.out.printf(colBld);
System.out.printf("|%-15s|",prodTxt);
for(int j = 0; j < colNbr-1; j++){ //Open for loop (columns 2)
sales[idx] = (int)(Math.random() * 16 + 1);
System.out.printf("%-10d|",sales[idx]);
idx++;
} //End for
System.out.printf("\n");
} //End for
int totalNbr = 0; //Placeholder zero
int regNbr = 0; //Placeholder zero
String totalTxt = "Final Total: ";
String regTxt = "Region Totals";
System.out.printf(colBld);
System.out.printf("|%-15s|%-10s|\n",regTxt,regNbr);
System.out.printf(colBld);
System.out.printf("|%s%s\n",totalTxt,totalNbr);
System.out.printf(colBld);
Here is what the code currently looks like once run:
|---------------|----------|----------|----------|----------|
|First Quarter |Region 1 |Region 2 |Region 3 |Region 4 |
|---------------|----------|----------|----------|----------|
|Product 1 |2 |10 |3 |1 |
|---------------|----------|----------|----------|----------|
|Product 2 |15 |15 |7 |16 |
|---------------|----------|----------|----------|----------|
|Product 3 |15 |13 |7 |9 |
|---------------|----------|----------|----------|----------|
|Product 4 |4 |14 |11 |11 |
|---------------|----------|----------|----------|----------|
|Region Totals |0 |
|---------------|----------|----------|----------|----------|
|Final total: 0
|---------------|----------|----------|----------|----------|
Honestly have no idea where to even begin with this. Any help is appreciated!
Since you have already sequentially filled the sales array with random Integer values to represent sequentially displayed Regions it is then a simple matter of stepping through the array elements in increments of the number of regions and summing the elements detected in each step.
To determine the actual number of Regions that will be displayed and the number of Region Totals to keep track of, we can base it from the value contained within the colNbr variable less 1 (5 - 1 = 4 regions will be displayed).
Knowing this we declare yet another integer Array named regionTotals and give it a length of 4:
int[] regionTotals = new int[colNbr-1];
Now it's a matter of stepping through the sales array elements and summing the proper sales array element to the proper regionTotal element, like this:
int regionCols = colNbr-1;
int[] regionTotals = new int[regionCols];
int stepCounter = 0;
for (int i = 0; i < sales.length; i++) {
stepCounter++;
if (stepCounter > regionCols) { stepCounter = 1; }
int regionIndex = (stepCounter - 1);
regionTotals[regionIndex]+= sales[i];
}
System.out.println("\nRegion Totals: " + Arrays.toString(regionTotals) + "\n");
Place the above code directly above the declaration & initialization of the totalNbr integer variable:
int totalNbr = 0; //Placeholder zero
How you format the regionTotals array elements into your table is up to you but do remember, the Array is zero based so the element at index 0 of the array contains the summation for Region 1.
I'm trying to build a sudoku solver. I know my code is messy and there will probably be a much simpler way to do it, but I would like finish the algorithm the way I started.
The algorithm starts doing what I want (filling the blank spaces with the first number that could fit), but when it reaches a point with no options, I don't know how to go back and erase the last number I inserted to try with another combination. But I can't just erase the last number from the matrix because it could be a number that wasn't placed by the algorithm.
If someone could help I would really appreciate it.
public class Backtracking{
public static void Sudoku(int[][] sudokuTable){
if (isAnswer(sudokuTable)){
printSudoku(sudokuTable);
}else{
for (int j = 1; j <=9; j++){
if (canfit(sudokuTable, j)){
addToSudoku(sudokuTable, j);
printSudoku(sudokuTable);
Sudoku(sudokuTable);
}
}
}
}
public static void addToSudoku(int[][] sudokuTable, int n){
int i = 0;
int j = 0;
boolean done = false;
while (i < 9 && !done){
while (j < 9 && !done){
if (sudokuTable[i][j] == 0){
sudokuTable[i][j] = n;
done = true;
}
j++;
}
i++;
}
}
public static void printSudoku(int[][] sudokuTable){
for (int i = 0; i < 9; i++){
for (int j = 0; j < 9; j++){
System.out.print(sudokuTable[i][j] + " ");
}
System.out.println();
}
System.out.println();
}
public static boolean isAnswer(int[][] sudokuTable){
int sum = 0;
for (int i = 0; i < 9; i++){
for (int j = 0 ; j < 9; j++){
if (sudokuTable[i][j] > 9 || sudokuTable[i][j] < 1)
return false;
else
sum++;
}
}
if (sum != 405)
return false;
return true;
}
public static boolean canfit(int[][] sudokuTable, int n){
int i = 0;
int j = 0;
boolean pos = false;
boolean fit = true;
while (i < 9 && !pos){
while (j < 9 && !pos){
if (sudokuTable[i][j] == 0)
pos = true;
else
j++;
}
if (!pos)
i++;
}
for (int k = 0; k < 9; k++){
if (sudokuTable[i][k] == n && k != j)
fit = false;
}
if (fit){
for (int l = 0; l < 9; l++){
if(sudokuTable[l][j] == n && l != i)
fit = false;
}
}
if (fit){
if (i >= 0 && i < 3)
i = 0;
else if (i >=3 && i < 6)
i = 3;
else if (i >=6 && i < 9)
i = 6;
if (j >= 0 && j < 3)
j = 0;
else if (j >=3 && j < 6)
j = 3;
else if (j >=6 && j < 9)
j = 6;
for (int m = i; m < i+3; m++){
for (int o = j; o < j+3; o++){
if (sudokuTable[m][o] == n)
fit = false;
}
}
}
return fit;
}
Try to return true or false from your Sudoko method.
when isAnswer() method returns true, print table. Then return true from Sudoko() method.
Now inside your for loop, where you are calling Sudoko() method recursively, check if it returns true, or false. If it returns true, that means your choice is correct and it leads to a solution, you need not to do anything else. If it returns false, remove the number you set using addToSudoko() method. Make the table as it was before calling addToSudoko() method and continue iterating.
And if your for loop, loops for 9 times and none of the number has a suitable spot, that means if loop ends, return false.
Hope this helps
Actually you can backtracking moves by using an array, each time a move is wrong you just start to remove some moves and try a different move, however this has a problem:
the complexity of trying all possible moves is huge (how long does it takes to try all digits on a number with 81 digits? even if you cut computation time here and there , you will need all the time of the universe)
the main problem in sudoku is that you have no clue which was the wrong move if you move randomly.
Assume the following case sudoky with 2x2 cells:
+----+----++-----+-----+
| 1 | 2 || 3 | 4 |
+----+----++-----+-----+
| 4 | 3 || 1 | 2 |
+====+====++=====+=====+
| 2 | 1 || 4 | 3 |
+----+----++-----+-----+
| 3 | 4 || 2 | 1 |
+----+----++-----+-----+
If you use your algorithm in the following (unsolved) case:
+----+----++-----+-----+
| 1 | || | 4 |
+----+----++-----+-----+
| | || | |
+====+====++=====+=====+
| 2 | || | |
+----+----++-----+-----+
| | 4 || | 1 |
+----+----++-----+-----+
it is possible he will run into the following sequence
+----+----++-----+-----+
| 1 | || 2 | 4 |
+----+----++-----+-----+
| | || 2 | |
+====+====++=====+=====+
| 2 | || | |
+----+----++-----+-----+
| | 4 || | 1 |
+----+----++-----+-----+
Actually the added "twos" are both wrong, but when your algorithm find that those are wrong because you have 2 "twos" in the same column, you don't know which one was the wrong one (the first added, the second added, or both?)
A correct backtracking algorithm would works like this:
You start with a 81 cells arrays, and you start placing numbers (in sequence).
.
for(int i=0; i<81; i++)
array[i] = TryNumber();
.
then you check after each added number if that was correct.
.
if(SomeNumberNotCorrect())
break; // you know you can stop "tryingnumbers" so you can save on loop executions
.
But you don't know which was the wrong number
Now writing a correct algorithm that solves sudokus by attemps and do not run in million of years is pretty long and I cannot write it here but I don't think the way you choosen is the best. The best way is to apply the same strategies used by players. Just keep in mind that if you want an algorithm to resolve sudokus in a similiar way to how Chess is played by computer your algorithm would require much more time than a Chess game (infact a computer cannot analize chess moves more than 5-6 turns). But infact Sudokus can be resolved with much faster algorithms.
Instead I've already done in past a simple solver you could actually try to apply the same strategies a player would use to solve it:
In example:
For each cell, check if current Sector, Column and Line have already all numbers except 1, then you can add that number. And to check that for each cells you just need 81*81*81 moves.
When your solver do not find anymore solutions on a Sudoku, it is just because you have to develop as player a new strategy and then you need to apply it to your program, in short you will have a program that will be able to solve every sudoku (not very hard, and actually this is the reason that there are a lot of free sudoku solvers out there).
How can I fill the last n cells (inclusive) of a 2d array in java?
This is what I've tried:
if(numOfUnusedCells != 0) {
for (int k = matrix[0].length; k >= numOfUnusedCells; k--) {
matrix[rows-1][k -1] = "*";
}
}
Example
for a 2d array as such as 2 elements to fill:
+---+---+---+
| | | |
+---+---+---+
| | * | * |
+---+---+---+
Arrays.fill can do that for you:
see this example where you can fill the 1st element of the array with -21
example:
final int[][] a2dArr = new int[3][3];
System.out.println("Before: " + Arrays.deepToString(a2dArr));
for (int i = 0; i < a2dArr.length; i++) {
Arrays.fill(a2dArr[i], 0, 1, -21);
}
System.out.println("After: " + Arrays.deepToString(a2dArr));