Java loops,how to increment by different values? - java

I have an array, and I'd like to go through it with a for loop in the following way:use 2 element then skip 2 elements,then use 2 elements etc.
So for instance if I have and int array : 1 2 3 4 5 6 7 8 9 10
I'd like to work with 1 and 2 then skip 3 and 4 ,then again work with 5,6 skip 7,8 etc.
Is this possible in java?

You can do something like this:
for (int i = 0; i < array.length - 1; i += 4) {
// work with i and (i + 1)
}

Yes, you need a loop, but two would be simpler.
for (int i = 0; i < N; i += 4)
for (int j = i; j < i + 1; j++)
System.out.println(j);
Also you can do
IntStream.range(0, N)
.flatMap(i -> IntStream.range(i+1, i+3))
.forEach(System.out::println):

Something along the lines of this pseudo code will do the job:
for (int i=0; i<array.length-3; i+=4) {
int first = array[i];
int second = array[i+1];
//int third = array[i+2]; //skip this
//int fourth = array[i+3]; //skip this
}
Note: normally when looping through an array you can just use i<array.length-1, but because you could be skipping 2 at that point I believe you want to decrease the "OK" length of the array by 2 more.
Update: actual working Java code using a toggle:
boolean skip = false;
for (int i=0; i<test.length-1; i+=2) {
if (!skip) {
System.out.println(test[i]);
System.out.println(test[i+1]);
}
//int third = array[i+2]; //skip this
//int fourth = array[i+3]; //skip this
skip = !skip;
}

You can introduce as many variables as you need inside of a for loop and iterate through those. It's similar to using two loops with the advantage being that there's no extra iterations being done.
The main thing here is that you're skipping four entries in your array every time. This applies to both variables, and you also want to be sure that both of them are less than the length of the overall array (so you don't step off of it by mistake).
for (int i = 0, j = i + 1; i < array.length && j < array.length; i += 4, j += 4) {
System.out.printf("(%d, %d) ", array[i], array[j]);
}

Related

How can I repeat text in a manipulative way, and repeat this action until my target has been reached?

How do I count up from 1 to a given number in triangular fashion?
Attempt
while (numbers <= number) {
System.out.println(numbers);
numbers++;
}
Target Output
1
1 2
1 2 3
I recommend you read about looping in Java, this is a base to start from.
int num = 10;
for(int i = 1; i < num; i++)
{
for(int j = 1; j <= i; j++)
{
System.out.print(j + " ");
}
System.out.print("\n");
}
This should provide the triangular structure you are looking for. Definitely do take a look at the link above. Since you are new to Java, you should take a walk through this code before simply copying it. Really try to see how it works and more importantly, why it works.

How to count the frequency of each string in the already sorted ArrayList without using Stream API, MAP, Hashset, collection API

I have tried using below code, though it works but does not satisfy the requirement.Please share your knowledge , Thanks
String temp;
for(int i = 0; i < lexicon.size(); i++)
{
for (int j = lexicon.size() - 1; j > i; j--)
{
if (lexicon.get(i).compareTo(lexicon.get(j)) > 0)
{
temp = lexicon.get(i);
lexicon.set(i,lexicon.get(j)) ;
lexicon.set(j,temp);
}
}
}
ArrayList<String> uniqueWords = new ArrayList<String>();
for(int i = 0; i < lexicon.size(); i++) //Removing duplicates
{
int wordCount = 1;
uniqueWords.add(lexicon.get(i));
for(int j = i+1; j < lexicon.size(); j++)
{
if(uniqueWords.get(i).equals(lexicon.get(j)))
{
wordCount++;
lexicon.remove(j);
}
}
System.out.println(uniqueWords.get(i) + " " + wordCount);
}
This is the output i am getting:
a 6
a 3
a 2
about 1
acknowledged 1
all 1
also 1
and 2
answer 1
at 2
austen 1
be 2
been 1
bennet 2
bennet 1
I need something like this: Word Count for that word
a 11
about 1
acknowledge 1
and so on
The problem is that you are removing elements from your lexicon at lexicon.remove(j); and also moving forward in your lexicon with your check at lexicon.get(j)
I don't want to give you the full code that works, because you won't learn anything from that, but I hope I gave you enough hint, to solve your problem. Try debugging your code, and see what happens with the variables :)
On removal at index j, j get's increased by j++, actually skipping one, where it should have continued without increasing.
As already sorted:
String word = uniqueWords.get(i);
int j = i+1;
while (j < lexicon.size() && word.equals(lexicon.get(j)))
{
wordCount++;
lexicon.remove(j);
}
(I'll give the code, as it shows a somewhat different approach.)

Manual array copy in a nested for loop

I trying to find all 2s, move them to the back of the array, and turn them into 0s without loosing the order of the array. For example, [1,2,3,2,2,4,5] would become [1,3,4,5,0,0,0]. My code works fine but the IDE is telling me that the nested for loop is copying the array manually and wants me to replace it with System.arraycopy(). How would I go about that?
Code looks like this:
int[] numbers = {1,2,3,2,2,4,5};
for (int i = 0; i < numbers.length; i++){
if (numbers[i] == 2){
for (int j = i; j < numbers.length - 1; j++){
numbers[j] = numbers[j + 1];
}
numbers[numbers.length-1] = 0;
i --;
}
}
The following statement:
for (int j = i; j < numbers.length - 1; j++){
numbers[j] = numbers[j + 1];
}
Can be replaced by:
System.arraycopy(numbers, i + 1, numbers, i, numbers.length - 1 - i);
IDEs like IntelliJ should suggest that automatically when you press alt + enter (default key combination).
Now about arraycopy()
From the documentation, java.lang.System.arraycopy() will copy n elements (last argument) from the source array (1st argument) to the destination array (3rd argument) with the corresponding indexes to start from (2nd and 4th arguments).
More specifically, when calling arraycopy(numbers, i + 1, numbers, i, numbers.length - 1 - i) the arguments are:
numbers: The source array.
i + 1: The starting position in the source array.
numbers: The destination array.
i: The starting position in the destination data.
numbers.length - 1 - i: The number of array elements to be copied.
In your case, elements will be copied from your array, to itself, but the fact that source starting position is shifted from the destination starting position will induce the global shifting you're after (moving elements to the left).
About the number of elements to be moved, it should move i elements minus the first one that doesn't move and only gets overwritten. Hence the length - 1 - i.
The inner loop could be replaced with an arraycopy, however, you don't need an inner loop:
int[] numbers = {1,2,3,2,2,4,5};
int j = 0;
for (int i = 0; i < numbers.length; i++){
if (numbers[i] != 2){
numbers[j++] = numbers[i];
}
}
while (j < numbers.length) {
numbers[j++] = 0;
}
UPDATE
Or even:
int[] numbers = {1,2,3,2,2,4,5};
int j = 0;
for (int n: numbers){
if (n != 2){
numbers[j++] = n;
}
}
Arrays.fill(numbers,j,numbers.length,0);
The key thing is pretty simple: if you can reduce the lines of code you are responsible for (for example by using utility methods such as Arrays.arraycopy()) - then do that.
Keep in mind: each line that you write today, you have to read and understand tomorrow, and to probably modify in 5 weeks or months from now.
But then: I think you are over-complicating things here. I would use a temporary list, like this:
List<Integer> notTwos = new ArrayList<>();
int numberOfTwos = 0;
for (int i=0; i<source.length; i++) {
if (source[i] == 2) {
numberOfTwos++;
} else {
notTwo.append(source[i]);
}
}
... simply append `numberOfTwo` 0s to the list, and then turn it into an array
You see: you are nesting two for-loops, and you are repeatedly copying around elements. That is inefficient, hard to understand, and no matter how you do it: way too complicated. As shown: using a second list/array it is possible to "solve" this problem in a single pass.
After replacing your inner loop with System.arrayCopy the code should look like:
int[] numbers = { 1, 2, 3, 2, 2, 4, 5 };
for (int i = 0; i < numbers.length; i++) {
if (numbers[i] == 2) {
System.arraycopy(numbers, i + 1, numbers, i, numbers.length - 1 - i);
numbers[numbers.length - 1] = 0;
i--;
}
}

Printing line of a given matrix

I'm trying to made a method that receives a matrix and prints its lines. For example:
line nb 1 : 3 2 5 6
line nb 2 : 7 9 0 1 4 3
line nb 3 : 3 5 3
I'd like to know why I cannot print the lines of the given matrix using this code. And also, why I cannot increment the variable k, that shows me the number of the line.
When I run this code it does not increment k. It always shows me the number 1 for the line
How can I fix my code?
public static void PrintLine(int[][] matrix){
for (i = 0; i < matrix.length; ++i){ // Loop all long the lines of the matrix
int k = 1; // Number of the line
System.out.print("Line nb " + k + matrix[i]);
k = k+1; // Increment the number of the line by 1
}
}
It's not so much that k does not get incremented; rather, you increment k only to discard it immediately, because the scope of the variable k is restricted to a single iteration (i.e., within the curly braces). The following should work:
for (int i = 0, k = 0; i < matrix.length; ++i, ++k) {
/* work in terms of i and k */
}
which, in your case, simplifies to using i and k for the same purpose:
for (int i = 0; i < matrix.length; ++i) {
System.out.print("Line nb " + i + matrix[i]");
}
Your k variable is initialized inside for loop. It means on each iteration it will be new variable. With initial 1 value.
Move it's itialization out of the loop:
int k = 1; // Number of the line
for (i = 0; i < matrix.length; ++i){ // Loop all long the lines of the matrix
As other have pointed out the scope of your k is incorrect, you can just use the value of i, also when you print your array you are getting the object reference details, you can use Arrays.toString() to print the values from an Array.
for (int i = 0; i < matrix.length; ++i) {
System.out.print("Line nb " + i +": "+ Arrays.toString(matrix[i]));
}

Find Duplicates In Arrays

I am writing a method that would take the values and the array and find duplicates. If there are duplicates, like for instance two values have the same value, I will multiple that value by 2. If two values have the same value, I will multiple that value by 3. This will continue until if seven values are the same. I will multiple that value by 7.
This is my source code.
public static double calculateWinnings(int[]numbers)
{
double total = 0;
for (int i = 0; i < numbers.length - 1; i++)
{
for (int j = i + 1; j < numbers.length; j++)
{
if(numbers[i] == numbers[j])
{
total = numbers[i] * .01;
System.out.println("Total is " + total);
return total;
}
}
}
return total;
}
If order doesn't matter, you should sort first, then analyze.
Sorting will put identical values next to each other, where you could more easily notice them in a for loop.
The Java Collections classes may also be of use here.
See for instance http://download.oracle.com/javase/tutorial/collections/intro/index.html
For instance, if you don't want to sort first and use a loop, you could use a HashMap from the collections classes.
HashMap<Integer, Integer> counts = new HashMap<Integer, Integer>();
for(int i=0; i < numbers.length; ++i){
Integer before = counts.get(numbers[i]);
if (before == null) before=0;
counts.put(numbers[i], before+1);
}
now you have a mapper from numbers to counts
later you can use something like max(counts.valueSet()) to find the maximum count
and then loop back through your hash to see which number caused that.
If you have same values at index 1, 4, 6, you will find them with
i j conclusion
--------------
1 4 2 values
1 6 3 values
4 6 4 values // oops! already counted
and so on. Well you would - but there is no so on, since you return on the first hit:
if(numbers[i] == numbers[j])
{
total = numbers[i] * .01;
System.out.println("Total is " + total);
return total; // oops!
}
Do you mean break?
You should provide some example inputs and outputs. It's not clear exactly what output you expect. Are you just looking to find the most duplicates and then multiply that number by the frequency it appears? For example:
1 2 5 5 5 7 8 8 = three 5's = 15
Or perhaps the two 8's wins because their total is 16? Or are you going to sum all of the duplicates? In any case I'd start with this, where MAX_NUM is the highest number you expect in the array:
int[] counts = new int[MAX_NUM];
for (int i = 0; i < numbers.length; i++) {
counts[numbers[i]]++;
}
Now you have the counts of each number. If you're looking for the number with the highest count:
int num = 0;
int best = 0;
for (int i = 0; i < counts.length; i++) {
if (counts[i] > best) {
num = i;
best = counts[i];
}
}
Now num * best would be 15 for my example. Now num will contain the number that occurs the most and best will be the count for it. If there are two numbers with the same count then the higher number will win. Perhaps though in my example above you want 16 instead of 15 because the two 8's have a greater sum:
int max = 0;
for (int i = 0; i < counts.length; i++) {
max = Math.max(i * counts[i], max);
}
Now max would have 16.

Categories

Resources