Loop for grabbing certain char's in a string - java

If I have a string and an int, I want to be able to create a loop that will print the first char of the string, followed by each the char at value of that int.
e.g. If I have the word "Miracle" and the int 2, the result should be "Mrce". My code does this, but stops a char short for certain words.
System.out.println(str.charAt(0));
while (n <= str.length())
{
System.out.println(str.charAt(n));
n = n+n;
}
This works for strings like "abcdefg" and int 3. It prints "adg", but if the string is "miracle" and int 2, it prints "mrc" and not "mrce".
I'm pretty sure the problem is in the "n= n+n" statement.
Because if the int is 3 and the string is greater than 3 it will loop, but in the n=n+n statement it will loop enough that n will be greater than str length and it halts.
How can I correct this?

You are right, your problem is with n=n+n because it multiple n with 2 in every step so you must change that.
change your code like this :
int m = 0;
while (m < str.length())
{
System.out.println(str.charAt(m));
m = m+n;
}

n = n+n; means that in each iteration you are multiplying your n by 2, so
iteration | n
----------+-------
1 | 3
2 | 3+3=6
3 | 6+6=12
and so on.
What you need is temporary variable (iterator) which will use n but will not change it.
Generally more readable way to write it would be with for loop like
for (int i = 0; i < str.length(); i = i+n){//or `i += n`
^^^^^^^^^ ^^^^^^^^^^^^^^^^ ^^^^^^^
// start at continue when in next step
System.out.print(str.charAt(i));
}

I'll answer with a counterquestion: where is this mentionned int? What walue should it have, and what value does it have?
In short, you should have one variable which has the step value and another variable which acts as a cursor.
Something like
int cursor = 0;
while (cursor <= str.length()) {
System.out.println(str.charAt(cursor));
cursor += stepValue;
}
Here you see that it is necessary to have two distinct variables here.

It is working for first few instances as 2+ 2 = 4, but after that - its doing 4 + 4 = 8, while you need is 4 + 2 = 6.
Take a new var (v), assign it the initial value, & instead of doing n = n + n, do
n = n + v

I think this is what you need
int n = 0;
int skip = 2;
while (n < str.length())
{
System.out.println(str.charAt(n));
n+=skip;
}

First of all, you have an error here:
n <= str.length()
It should be
n < str.length()
because strings are indexed from 0 to length-1.
Also make sure you are indexing from 0, not from 1.
Another thing is that you are adding a bigger number each time. So yes - you are right about n+n - it's wrong.
You should do something like this:
n = ...;
for (int i = 0; n * i < str.length(); ++i)
{
int index = n * i;
System.out.println(str.charAt());
}
This way you have n * 0, n * 1, n * 2, ..., which is what you want.

There are two things wrong in your code:
If n == str.length(), it will throw an exception, as it tries to
access str.charAt(n), which in that case doesn't exist.
Another thing, n = n + n will change the value of n every time, so you
will add a bigger number every time instead of the same.
You could use a for-loop for a cleaner approach though:
for (int i = 0; i < str.length(); i += n) {
System.out.println(str.charAt(i));
}

Related

Filling an array with a mathematical sequence

I want to write a code that asks for three numbers dig(1), dig(2), dig(3) and displays a sequence of numbers dig(1), dig(2), dig(3), ..., dig(n) according to this rule:
a = dig(2) - dig(1)
b = dig(3) - dig(2)
dig(n) = dig(n-1) + a if n is odd
dig(n) = dig(n-1) + b if n is even
Example:
7, 8, 5, 6, 3, 4, 1, 2, -1, 0
It asks an user for three integers dig1, dig2, dig3
It asks a number N ≥ 3 which will be the whole sequence count.
It prints a sequence beginning with
Then prints the sequence, beginning with the three leading integers, followed by N-3 other terms that follow the pattern defined by the first three integers. See examples below for more information.
(The sequence begins with n = 1, but of course the array starts at 0.)
int dig1 = 0;
int dig2 = 0;
int dig3 = 0;
int a;
int b;
int n = 0;
int i;
dig1 = scnr.nextInt();
dig2 = scnr.nextInt();
dig3 = scnr.nextInt();
n = scnr.nextInt();
int[] array = new int[n];
array[0] = dig1;
array[1] = dig2;
array[2] = dig3;
a = dig2 - dig1;
b = dig3 - dig2;
for (i = 3; i < n; i++){
if(i%2 == 0){
array[i] = b + array[i-1];
}
else{
array[i] = a + array[i-1];
}
}
System.out.println(array[i]);
}
}
whenever I try to print this out, I get this error:
java.lang.ArrayIndexOutOfBoundsException
Another example: if I put in the numbers: 0 1 0 9 into my input, I should receive back the sequence 0 1 0 1 0 1 0 1 0
Printing array[n-1] gives me back just the final output. I'm trying to iterate through each number.
Sorry if that's unclear, but any help would be great, thank you.
Your System.out.println(array[i]); seems to be out of the for loop. Then i will be equal to n. And there is no element with index n in array with length n. The elements are from 0 to n-1.
At first I thought that you were choosing an array size less than 3, and that the code was failing here, during the initialization of the array:
array[0] = dig1;
array[1] = dig2;
array[2] = dig3;
But now, I actually think that the last line of code is the problem. Have a closer look at your for loop:
for (i=3; i < n; i++) {
if (i % 2 == 0) {
array[i] = b + array[i-1];
}
else {
array[i] = a + array[i-1];
}
}
System.out.println(array[i]);
Appreciate that at the end of the for loop, i, the loop counter, will always be n, the size of the array. Accessing array[n] will always be out of bounds, because an array in Java has a highest addressable index of one less than the actual number of buckets. So, if you were intending to just print the final element, then use this:
System.out.println(array[i-1]);
or
System.out.println(array[n-1]);
at the line n=scrn.nextInt(), you are assigning to n a integer from scrn but you don't know the value of that integer.
Then with this:
int[] array = new int[n];
Your array is of size of n elements starting from index 0 to index n-1.
So let's suppose the value you affected to n with .nextInt() is inferior to 3: initial value of i, the loop will even not be reached, because you will be out of bounds just here:
array[0] = dig1;
array[1] = dig2;
array[2] = dig3;
since you will be attempting to affect a value on an array at an index that does not exists (n is inferior to three but you are trying to affect three values in an array of size n).
Then if n is superior to 3, since your printing code is out from the loop, the value of i is equal to n and there is no value at index n. remember, the loop will leave only if the condition i<n is false and to reach that condition i must be equal or superior and that will lead to an IndexOutOfBoundsException on printing.
I think you printing line code should be inside the for loop.

How to define number sequence in string?

I have a task to create a string with a non-defined length (input digits from the keyboard until the user presses "Enter"), then I have to define how many of digits are in sequence. Unfortunately I can't handle this. I think I'm almost there but I'm not. I've created the string which I hoped to copy character by character to an array and then compare each digit with the next one, but I have trouble with copying characters into an array.
Here's my code:
int sum = 0;
String someSymbols = sc.nextLine();
int array [] = new int[someSymbols.length()];
for(int i=0; i<someSymbols.length(); i++){
for (int j=0; j<=array.length; j++){
array[j] = someSymbols.charAt(i);
}
sum++;
}
Not sure of what you want to achieve but here are 2 examples for inspiration:
Taking digits until reaching a different digit. Ignoring non digits
String s = "22u223r5";
String digitsOnly = s.replaceAll("[^\\d.]", "");
int firstDifferentDigit = -1;
for(int i = 1; i < digitsOnly.length(); i++) {
if(digitsOnly.charAt(i) != digitsOnly.charAt(i-1)) {
firstDifferentDigit = i;
break;
}
}
System.out.println("firstDifferentDigit:"+firstDifferentDigit);
System.out.println(digitsOnly.substring(0,firstDifferentDigit));
Outputs
firstDifferentDigit:4
2222
Taking digits until first non digit
String s = "124g35h6j3lk4kj56";
int firstNonDigitCharacter = -1;
for(int i = 0; i < s.length(); i++) {
if(s.charAt(i) < '0' || s.charAt(i) > '9') {
firstNonDigitCharacter = i;
break;
}
}
System.out.println("firstNonDigitCharacter:"+firstNonDigitCharacter);
System.out.println(s.substring(0,firstNonDigitCharacter));
Outputs
firstNonDigitCharacter:3
124
EDIT
This works for how you described the exercise:
String someSymbols = "72745123";
List<String> sequences = new ArrayList<>();
boolean inSequence = false; // will flag if we are currently within a sequence
StringBuilder currentSequence = new StringBuilder(); // this will store the numbers of the sequence
for(int i = 0; i < someSymbols.length(); i++) {
char currentChar = someSymbols.charAt(i);
char nextChar = 0;
if(i < someSymbols.length()-1)
nextChar = someSymbols.charAt(i+1);
// if next number is 1 more than the current one, we are in a sequence
if(currentChar == nextChar-1) {
inSequence = true;
currentSequence.append(String.valueOf(currentChar));
// if next number is NOT 1 more than the current one and we are in a sequence, it is the last of the sequence
} else if(inSequence) {
currentSequence.append(String.valueOf(currentChar));
sequences.add(currentSequence.toString());
currentSequence = new StringBuilder();
inSequence = false;
}
}
System.out.println(sequences);
Outputs
[45, 123]
Thanks a lot! I made it with your help! It turns out that the task was to count how many numbers occur in the string of any symbols. As simple as that. My bad! But I'm grateful to be part of this forum :)
Here's the code:
String f = sc.nextLine();
int count = 0;
for(int i=0; i<f.length(); i++){
if((f.charAt(i)>='0') && (f.charAt(i)<='9')){
count++;
}
}
System.out.println("The numbers in the row are : " + count);
I deleted my first answer, because I got the question wrong, thought it's about a character sequence, of which some happen to be digits.
Trying to wrap my head around the new functional style in Java8, but conversion is complicated and full of pitfalls. Surely, this isn't canonical. I guess a collector could be appropriate here, but I broke out and made half of the work in an recursive method.
import java.util.*;
import java.util.stream.*;
String s = "123534567321468"
List<Integer> li = IntStream.range (0, s.length()-2).filter (i -> (s.charAt(i+1) != s.charAt(i)+1)).collect (ArrayList::new, List::add, List::addAll);
li.add (s.length()-1);
int maxDiff (int last, List<Integer> li , int maxdiff) {
if (li.isEmpty ())
return maxdiff;
return maxDiff (li.get(0), li.subList (1, li.size () - 1), Math.max (li.get(0) - last, maxdiff));
}
int result = maxDiff (0, li, 0);
It starts elegantly.
IntStream.range (0, s.length()-2).filter (i -> (s.charAt(i+1) != s.charAt(i)+1))
| Expression value is: java.util.stream.IntPipeline$9#5ce81285
| assigned to temporary variable $20 of type IntStream
-> $20.forEach (i -> System.out.println (i));
2
3
8
9
10
11
12
That's the List of indexes, where chains of numbers are broken.
String s = "123534567321468"
123 is from 0 to 2, 5 is just 3, 34567, the later winner from 4 to 8, ...
Note that we needn't transform the String into Numbers, since the characters are chained in ASCII or UTF-X one by one, like numbers.
To convert it into a List, the complicated collect method is used, because Array of primitive int doesn't work well with List .
For the last interval, li.add (s.length()-1) has to be added - adding elements wouldn't work with array.
maxDiff protocolls the max so far, the last element and repeatedly takes the head from the list, to compare it with the last element to build the current difference.
The Code was testet in the jshell of Java9, which is an amazing tool and needs no embedding class, nor 'main' for snippets. :)
Just for comparison, this is my solution in scala:
val s = "123534567321468"
val cuts = (0 to s.length-2).filter (i => {s.charAt(i+1) != s.charAt(i)+1}).toList ::: s.length-1 :: Nil
(0 :: cuts).sliding (2, 1).map {p => p(1) - p(0)}.max
Sliding(a,b) defines a window of width a=2 which moves forward by b=1.

Finding all the number combos in array that add up to input number

Hey I'm working on figuring out an algorithm that takes a user-entered number and then goes through an array of size 50 filled with random numbers between 1 and 100 and finds all the combinations of numbers that add up to the input number.
For example, given an array of integers [3,6,1,9,2,5,12] and being passed the integer value 9, you would return [[3,6],[6,1,2],[9],[3,1,5]]. Order of returning the results in the array does not matter, though you should return unique sets (ie. [6,3] and [3,6] are the same and only one should be returned). Also, the individual results should be in the order they are found (ie [6,1,2] should be returned, not [1,2,6]).
As I've started writing code, the first solution that I came to seems extremely in-efficient. I'm currently trying to separate each combo into it's own array, and every time a number gets added to the array, a check is done to see if the numbers equal the input, are still less than, or go over it. It's not working properly, and I feel like this might be an inefficient way to do it:
for (int i = 0; i < list.length; i++) {
List<Integer> combo = new ArrayList<Integer>();
int counter = 0;
int current = list[i];
if (current == input){
System.out.println(i);
}
else if (current > input) {
continue;
}
else if (current < input) {
combo.add(current);
if (combo.size() >= 2) {
for (int j = 0; j < combo.size(); j++) {
counter += combo.get(j);
if (counter == input) {
System.out.println("Success");
break;
}
else if (counter < input) {
continue;
}
else if (counter > input) {
break;
}
}
}
}
}
This is an idea, I don't have a working code. Try to use recursion, test all combinations with the biggest possible number plus all the rest without it. Function like: Sums(Number, maxN), (maxN is maximum number which we can take - in first call it's 9)
For your example would be:
1. As suggested, sort them and cut bigger than input.
2. Check if the maxN is greater than the minimum required to make a sum, in your example it is 5 (can't make 9 from numbers smaller than 5 in your set); if it's not return (base case).
3. Is maxN equal tu input? (9 in first call)
a) Yes - first solution subset [9] + Sums(Number, dec(maxN)) (dec(maxN) will be 6 in first call)
b) No - recursively check if 'Number - maxN' could be built from numbers from your set, Sums(Number - maxN, dec(K) or max number of 'Number - maxN' (depends what is smaller)) + Sums(Number, dec(maxN)) - add the rest.
Here is code to count only, ways to write a number as sum of squares, it passed HackerRank tests:
import math
def minArgument(x):
s = 0
i = 1
while s < x:
s = s + i * i
i = i + 1
return i - 1
def maxPower(a):
return math.floor(math.sqrt(a))
def sumOfSquares(M, K, cnt):
if M < 1:
return cnt
lowerLimit = minArgument(M)
if K < lowerLimit:
return cnt
else:
if K * K == M:
return sumOfSquares(M, K - 1, cnt + 1)
else:
return sumOfSquares(M, K - 1,sumOfSquares(M - K * K,
min(maxPower(M - K * K), K - 1), cnt))
After easy change, this gives you number of solutions. I don't see how to build a list with combinations as a return value now...

looping a string to an int amount of times and shortening it

If I input a string str and an int n, I need to create a loop that will print the beginning of the string n times, with the first n chars, then the first n - 1, then n - 2, and so on, until it prints just the first character.
So for example, "Apples" and "3" would result in "AppApA".
I have created the following, which works... somewhat. "n" being the int.
int i = 0;
while(i <= n)
{
System.out.println(str.substring(0, Math.min(str.length(), n)));
n = n - 1;
i++;
}
This works for ints <= 2; if I input a string like "Chocolate" and the int 3, I will get "ChoCh" when I should be getting "ChoChC".
This has had me stumped for about 30 minutes. Any insight is appreciated.
Get rid of the i variable. You need to run the loop until the substring's length is 1, so:
while (n > 0)
{
System.out.println(str.substring(0, Math.min(str.length(), n)));
n = n - 1; // n-- would do the same thing here
}
Since you both increment i and decrement n, your loop only happens roughly n/2 times. This might have been clearer to you if you had tried in a debugger with a larger value of n, obviously paying particular attention to the loop condition.

Time Complexity of a for loop

So I'm not really understanding a few things here, when counting the steps in for(int i = 1; i <= n; i++) the answer is:
1 for assignment int i = 1, n+1 for i <= n and n for i++ which comes out to a total of 2n+2. My confusions is in 3 parts:
1.) Isn't the assignment int i = 1; also n? If lets say, n = 5, won't we end up assigning int i = 2, int i = 3... etc?
2.) For i <= n, is it n+1 because you are performing n checks and + 1 when it's false?
3.) Last, is i++ n because you are performing n additions?
For loop looks like for(INIT; CONDITION; INCREMENT) { /* ... */ }. The INIT part executes once only. This is equivalent to:
INIT
while(CONDITION)
{ /* ... */
INCREMENT
}
The initialization int i=1; is performed only one time at the beginning of the loop, regardless of n.
As for 2) and 3), you are correct.

Categories

Resources