Formatting with Array[i] Logic - java

I'm trying to build a program that prints 75 random caps and lowercase letters, 25 per line. I think I have all the logic worked out, but whenever I run it the formatting is all off and rather than printing 25 characters per line, it prints a random number. Here's my code so far:
char allLetters[] = new char[3700];
for(int i = 1; i <= 75; i++) { //Begin for loop
int max = 122;
int min = 65;
allLetters[i] = (char)(Math.random() * (max - min) + min);
if(i % 25 != 0){
if (allLetters[i] <= 90) {
System.out.printf("%s,",allLetters[i]);
}
if (allLetters[i] >= 97) {
System.out.printf("%s,",allLetters[i]);
}
} //Close if
else {
if (allLetters[i] <= 90) {
System.out.printf("%s\n",allLetters[i]);
}
if (allLetters[i] >= 97) {
System.out.printf("%s\n",allLetters[i]);
}
}
} //End for
Currently, the output is something like:
U,i,y,e,v,T,G,p,P,a,U,G,e,B,w,U,o,F,G,w,j,m,R
O,X,w,w,u,p,t,g,X,J,R,c,w,I,d,H,R,m,y,b,o
C,p,M,F,X,U,v,O,a,Y,F,E,x,s,x,k,C,b,D,R,r,H
I've tried using different variables besides i, playing around with numbers and such but I can't seem to find the exact flaw in the logic that throws the formatting off. Any help would be greatly appreciated!

The problem with your logic is that you are counting each chosen character even when you do not print it. The ASCII characters falling between 90 and 97, exclusive, are not characters, and you rightfully skip printing them. Yet the loop is still counting those iterations as if a valid letter has been printed. This is resulting in an incorrect count in the output.
The workaround used in the code snippet below is to keep picking characters in a loop until we actually get a lowercase or uppercase letter. Only then do we continue with your previous logic.
char allLetters[] = new char[3700];
int max = 122;
int min = 65;
for (int i = 1; i <= 75; i++) {
char next;
do {
next = (char)(Math.random() * (max - min) + min);
} while (next > 90 && next < 97);
allLetters[i] = next;
if (i % 25 != 0) {
System.out.printf("%s,", next);
}
else {
System.out.printf("%s\n", next);
}
}
Demo

Your two conditions that you put on your random characters, namely allLetters[i] <= 90 and allLetters[i] >= 97, do not cover the entire interval of possible characters, which in your program is 65 to 122, inclusive. When a character between 91 and 96 gets generated, your program does not print anything. The probability of getting one of these six random characters is roughly 10%, so you get 21..23 characters printed.
If you really want to skip these six characters, fix the problem by using a while loop instead of a for loop, and increment the counter of printed characters only when you print something:
int printed = 0;
while (printed != 75) {
char ch = (char)(Math.random() * (max - min) + min);
if (ch >= 91 && ch <= 96) continue;
printed++;
System.out.print(ch);
if (printed % 25 == 0 {
System.out.println();
} else {
System.out.print(',');
}
}

I was looking at your problem, and there's a "clever" solution using Java 8+ IntStream and lambdas. Generate 75 random int(s) between 0 and 26, map each value to a one-character String offset from either 'a' or 'A' by using nextBoolean() from Random. Collect that to a single seventy-five character String. Then print the three twenty-five character substring(s) we're interested in. Like,
Random rand = new Random();
String s = IntStream.generate(() -> rand.nextInt(26)).limit(75)
.mapToObj(i -> Character.toString(
rand.nextBoolean() ? (char) (i + 'a') : (char) (i + 'A')))
.collect(Collectors.joining());
System.out.println(s.substring(0, 25));
System.out.println(s.substring(25, 50));
System.out.println(s.substring(50));

Related

Incremented by a value x but it gets incremented by value x-1

I am implementing an Algorithm where when user gives input string, every character in string (if it is alphabet) should be incremented by value given(here rotator). I am playing with this code for 2 hr but can't figure out why when i increment by value rotator, it gets incremented by rotator-1.
public class Solution {
public static void main(String[] args) {
/* Enter your code here. Read input from STDIN. Print output to STDOUT. Your class should be named Solution. */
Scanner in = new Scanner(System.in);
int length = in.nextInt();
String input = in.next();
int nextvalue = 0;
int temp = 0;
char array[] = input.toCharArray();
int rotator = in.nextInt();
for(int i = 0; i < length; i++){
if((array[i] >= 'a' && array[i] <= 'z') || (array[i] >= 'A' && array[i] <= 'Z')){
nextvalue = (int)array[i] + rotator;
array[i] = (char)nextvalue;
if((int)array[i] > (int)'z'){
temp = (int)array[i] - (int)'z';
nextvalue = (int)'a' + temp -1;
array[i] = (char)nextvalue;
}
else if((int)array[i] > (int)'Z'){
temp = (int)array[i] - (int)'Z';
nextvalue = (int)'Z' + temp -1;
array[i] = (char)nextvalue;
}
}
}
System.out.println(array);
}
}
Inside first if there are two if statements to handle(Overflow condition) if letter is > z or >Z. Now if I Remove those two statements everything except overflow condition is correctly printed
(without overflow condition)
Sample I/P :
11 <- String length
middle-Outz
2 <- rotator
Sample O/P :
okffng-Qwv| <- Overflow condition not handled
(with overflow condition)
Sample I/P :
11
middle-Outz
2
Sample O/P :
njeemf-Qvub <- Overflow handled but everything else incremented by rotator - 1 except 'Q'
Why is this happening? I also checked using print statement in inner if condition , it executes only one time for this input since there is only one overflow condition.
Help/Suggestion appreciated.Thanks.
I think the easiest way to handle the overflow cases is to use the modulus operator to let the character wrap-around any number of times to land in the current logical position. Something like this should work:
for (int i=0; i < length; i++) {
if (array[i] >= 'a' && array[i] <= 'z') {
int currDiff = (int)array[i] - (int)'a';
int newPos = (int)'a' + ((rotator + currDiff) % 26);
array[i] = (char)newPos;
}
else if (array[i] >= 'A' && array[i] <= 'Z') {
int currDiff = (int)array[i] - (int)'A';
int newPos = (int)'A' + ((rotator + currDiff) % 26);
array[i] = (char)newPos;
}
}
I tested this code using an input string of abcdefg and a rotator value of 51, which returned zabcdef. This is expected, because we rotated one step short of two complete rounds. Hence, the a landed on z, after one complete rotation, and the following characters followed suit.
Note that there is a much nicer way of handling the calculus of character positions here, but this answer stays true to the way you were doing it in your original question.
Final note:
The modulus operator % returns the remainder of the division of the number which preceeds it and proceeds it. In the solution I gave above, I take the effective rotator % 26. Here, the effective rotator is the current distance of the letter from either a or A plus however many steps we want to rotate. By taking this number mod 26, we always will end up with a number between 0 and 25. Hence, we will always take between 0 and 25 steps from a or A, which is the behavior you want in your program.
Because you are modifying it twice in your loop.
for(int i = 0; i < length; i++){
if((array[i] >= 'a' && array[i] <= 'z') || (array[i] >= 'A' && array[i] <= 'Z')){
nextvalue = (int)array[i] + rotator;
array[i] = (char)nextvalue; //<-- modifies from m to o
if((int)array[i] > (int)'z'){
temp = (int)array[i] - (int)'z';
nextvalue = (int)'a' + temp -1;
array[i] = (char)nextvalue;
}
else if((int)array[i] > (int)'Z'){
temp = (int)array[i] - (int)'Z';
nextvalue = (int)'Z' + temp -1;
array[i] = (char)nextvalue; //<--modifies again from o to n
}
}
}
The mistake is in this line:
if ((int) array[i] > (int) 'Z') {
You have to keep in mind that lowercase letters come "after" uppercase letters: 'Z' is represented by 90, and (for example) 'j ' is represented by 106 (for more info see this). The reason why 'Q' isn't affected by this mistake is because it is also a capital letter, and thus has a smaller decimal representation than 'Z'.
To fix this, you have to replace the line of code above with something along the lines of this:
if ((int) array[i] > (int) 'Z' && (int) array[i] <= (int) 'Z' + rotator) {
Instead of
nextvalue = (int)'Z' + temp -1;
Shouldn't it be
nextvalue = (int)'A' + temp -1;

Show a number line based on the given string

I am stuck in my project where we have to show a string of line in the number line scale so later we can delete or add characters to that string. I am not sure how to print out the scale in 5s based on the length of the string.
Ex:
0 5 10 15 20
|----+----|----+----|-
This is the first line
Then, the user will choose the characters they want to delete from the string using from position and to position. It will show what position the user chose from the string and delete.
Ex:
from position: 12
to position: 18
0 5 10 15 20
|----+----|----+----|-
This is the first line
^^^^^^^ --> // this will be deleted
y/n: y
0 5 10 15
|----+----|----+
This is the ine
I was able to delete the characters but I do not know how to show the number line based on a string. Here is my code so far:
public void showNumberLine(String line)
{
int lineCount = line.length(); // getting the length of the string being passed in
String numberLine = "";
for(int i = 0; i <= lineCount; i++) //
{
numberLine = "" + i;
System.out.println("|----+----|----+----|-");
}
}
public void deleteSubString()
{
Scanner keyboard = new Scanner(System.in);
showNumberLine(textOfLine); // this will print out then number line and the line
System.out.print("from position: ");
int fromIndex = keyboard.nextInt();
System.out.print("to position: ");
int toIndex = keyboard.nextInt();
if(fromIndex < 0 || fromIndex > numOfChar || toIndex < 0 || toIndex > numOfChar)
{
System.out.println("Cannot delete at the given index: Index Out of Bounds");
}
/*
* Create a new number line where it shows what is going to be deleted
*/
String newLineOfString = textOfLine.substring(fromIndex, toIndex);
textOfLine = textOfLine.replace(newLineOfString, "");
System.out.println(newLineOfString);
}
I would recommend you to implement a method printScale or something like that which takes a String or an int as argument and prints these two lines for you.
You sad you already can remove the characters so if you have a String with the value "This is the ine" as you showed in your example you could call the method like this:
printScale(myNewString.length());
This method could look something like this (not perfect but works):
public void printLine(int amountOfCharacters) {
StringBuilder lineNumber = new StringBuilder();
StringBuilder lineScaleSymbols = new StringBuilder();
for (int i = 0; i < amountOfCharacters; i++) {
if (i % 10 == 0) {
if (i < 10) {
lineNumber.append(i);
} else {
lineNumber.insert(i -1, i);
}
lineScaleSymbols.append('|');
} else if (i % 5 == 0) {
if (i < 10) {
lineNumber.append(i);
} else {
lineNumber.insert(i -1, i);
}
lineScaleSymbols.append('+');
} else {
lineNumber.append(' ');
lineScaleSymbols.append('-');
}
}
System.out.println(lineNumber.toString());
System.out.println(lineScaleSymbols.toString());
}
Hope this helps.
You're on the right track with your showNumberLine method.
Let's outline exactly what you need to do:
determine the length of the string
generate a number line of the same length as the string
every character ending with 0 will be the special character |
every character ending in 5 will be the special character +
every other character will be -
You could make your loop like this, using the modulus operator to determine which character to write:
for(int i = 0; i < line.length(); i++) {
if(i % 10 == 0) {
// the number is divisible by 10 (ends in zero)
System.out.print("|");
} else if(i % 5 == 0 && i % 10 != 0) {
// the number is divisible by 5 and not divisible by 10 (ends in 5)
System.out.print("+");
} else {
System.out.print("-");
}
System.out.println();
}
Output:
|----+----|----+----|----+----|----+----|---
The quick brown fox jumped over the lazy dog
You'll need some more code to write out the digits (0, 5, 10, 15) above the number line, I'll leave that to you. It will be similar logic but there are subtle issues to consider as the length of the numbers is 1 character, then 2 characters, then 3 characters as they increase (0, 5, 10, 15, ... 100, 105). At some point you'll have to stop as the numbers won't fit in the space.

print two digit numbers which are less than or equal to 56 and the sum of digits is greater than 10 JAVA

why the following method doesn't work for printing two digit numbers which are less than or equal to 56 and the sum of digits is greater than 10 in JAVA
for (int i = 10; i <= 99; i++) {
String str = Integer.toString(i);
int sum = (str.charAt(0) + str.charAt(1));
if (sum > 10 && sum<=56) {
System.out.println("The first operation " + sum);
}
}
The third line: int sum = (str.charAt(0) + str.charAt(1)); is one of the problems. When i is 10, str.charAt(0) evaluates the the character 1 which has ascii value 49 and str.charAt(1) evaluates to the character 0 which has ascii value 48 producing a sum of 97 instead of the desired 1.
Instead you could use the modulus operator to strip-off the digits as needed. For example: int sum = ( i / 10 ) + (i % 10);.
*also, the range of i in your for loop should be adjusted as other users have commented.
Since you know any number greater than 56 won't pass your criteria, you need to change your loop to go from 10 to 56. Thus, you can exclude the second part of the if statement. Change the for loop to:
for (int i = 10; i <= 56; i++) {
and your if statement to:
if (sum > 10) {

How to check values in a string?

So i have a string in military time format : "1532" corresponding to 3:32pm.
I'm trying to write a method to check if each digit in time string is an appropriate digit. So the first element cannot be greater than 2 or equal to 0, and so forth. Currently, my code doesn't run past the second log statement and I'm hoping you guys could help!
cheers!
String mOpen = "1532";
Log.d("hoursTesting","pass1, length is > 2");
if(mOpen.getText().length() == 4)
{
Log.d("hoursTesting","pass2, length is == 4");
char[] tempString = mOpen.getText().toString().toCharArray();
if(tempString[0] != 0 && tempString[0] < 3)
{
Log.d("hoursTesting","pass3, first index is != 0 and < 3");
if(tempString[0] == 1)
{
Log.d("hoursTesting","pass4, first index is 1");
if(tempString[2] <= 5)
{
Log.d("hoursTesting","pass5, third index is <= 5, success!");
}
}
else //tempString[0] is equal to 2
{
Log.d("hoursTesting","pass4, first index is 2");
if(tempString[1] < 4)
{
Log.d("hoursTesting","pass5, second index is <3");
if(tempString[2] <= 5)
{
Log.d("hoursTesting","pass6, third index is <= 5, success!");
}
}
}
}
}
tempString contains characters, not numbers.
i.e. '0' not 0 etc.
Easiest fix is to compare characters e.g. tempString[0] == '1' Alternatively, you can do something like int digit1 = tempString[0] - '0'; - but that kind of assumes you already know you just have digits in the string.
Note that cos of those clever ASCII guys and their tricky character set '0' < '1' < '2' etc, so you can still say if (str[0] < '2') etc. You just need to be a bit careful that you are only dealing with digits.
Personally I'd convert the first 2 chars to a number and the second 2 chars to a number and then just check 0 <= number1 <= 23 and 0 <= number2 <= 59.
You are comparing char with int here:
if(tempString[0] != 0 && tempString[0] < 3)
It should work like this:
if(tempString[0] != '0' && tempString[0] < '3')
I would substring the hours and minutes components and then check to see if each one be in range:
public boolean isTimeValid(String mOpen) {
int hours = Integer.parseInt(mOpen.substring(0, 2));
int minutes = Integer.parseInt(mOpen.substring(2));
if ((hours >= 0 && hours <= 24) && (minutes >= 0 && minutes <= 59)) {
return true;
}
else {
return false;
}
}

Output of converting string into number does not come as expected

Given a string as input, convert it into the number it represents. You can assume that the string consists of only numeric digits. It will not consist of negative numbers. Do not use Integer.parseInt to solve this problem.
MyApproach
I converted string to char array and stored the original number but I am unable to convert it into a single number
I tried converting individual elements but the digits can be of any length.So,It was difficult to follow that approach.
Hint:I have a hint that the numbers can be added using place values
For e.g if the number is 2300.I stored each number in the form of arrays.Then it should be 2*1000+3*100+0*10+0=2300
But I am unable to convert it into code.
Can anyone guide me how to do that?
Note I cannot use any inbuilt functions.
public int toNumber(String str)
{
char ch1[]=str.toCharArray();
int c[]=new int[ch1.length];
int k=0;
for(int i=0;i<c.length;i++)
{
if(ch1[i]==48)
{
c[k++]=0;
}
else if(ch1[i]==49)
{
c[k++]=1;
}
else if(ch1[i]==50)
{
c[k++]=2;
}
else if(ch1[i]==51)
{
c[k++]=3;
}
else if(ch1[i]==52)
{
c[k++]=4;
}
else if(ch1[i]==53)
{
c[k++]=5;
}
else if(ch1[i]==54)
{
c[k++]=6;
}
else if(ch1[i]==55)
{
c[k++]=7;
}
else if(ch1[i]==56)
{
c[k++]=8;
}
else if(ch1[i]==57)
{
c[k++]=9;
}
}
}
You don't need to do powers or keep track of your multiplier. Just multiply your running total by 10 each time you add in a new digit. And use c - '0' to turn a character into a number:
int n = 0;
for (int i = 0; i < str.length(); i++) {
n = n * 10 + str.charAt(i) - '0';
}
So for example for 1234 it goes
0 * 10 + 1 = 1
1 * 10 + 2 = 12
12 * 10 + 3 = 123
123 * 10 + 4 = 1234
A digit character ('0'-'9') can be converted into an integer value (0-9) using:
ch - '0'
This is because the digit characters are all consecutive in ASCII/Unicode.
As for calculating the full number, for the input 2300, you don't want:
2 * 1000 + 3 * 100 + 0 * 10 + 0
Instead, you'll want a more incremental approach using a loop:
r = 0
r = r * 10 + 2 (2)
r = r * 10 + 3 (23)
r = r * 10 + 0 (230)
r = r * 10 + 0 (2300)
This is much better than trying to calculate 1000 (Math.pow(10,3)), which your formula would require.
This should be enough information for you to code it. If not, create a new question.
If you loop through the char array you have and take the last value, put it through an if statement and add to an to number integer whatever that number is (use 10 if statements). Next go to the second to last value, and do the same thing only this time multiply the resulting numbers by 10 before adding it to the total number. Repeat this using 1 * 10^(value away from end) being multiplied to the number gotten from the if statements.
Well what comes to my mind when seeing this problem is to multiply the numbers you are getting with your current code with the place they have in the charArray:
int desiredNumber = 0;
for(int k=1; k<=c.length; k++) {
desiredNumber += c[k] * (Math.pow(10, c.length - k));
}
If you are not allowed to use the Math.pow() function then simply write one yourself with aid of a loop.
Greetings Raven
You can do
int no = 0;
for(int i = 0; i < c.length; i++){
no += c[i] * Math.pow(10, c.length - 1 - i);
}

Categories

Resources