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.
Related
I had an interview and I've been asked to print numbers from 1 to a 1000 digit number -
1,
2,
3,
.
.
.
.,
999999999999999999999999999999999999999999999999........
I couldn't solve it but I'm still looking for the best way to do it, because obviously, you cant use integers or floats in a case like this and because it's a job interview I couldn't use any libraries that can handle it.
Can anyone think of a good solution? preferably in Java/pseudocode.
I had an interview and I've been asked to print numbers from 1 to a 1000 digit number
I guess the kind of answer they expected you to give is:
"We need to print the numbers from 1 to 10^1000-1. Last year, $80e9 worth of processors were sold worldwide [1], even if one processor per dollar had been sold and each processor was a thousand times faster than the fastest of them all [2] and only one instruction was used to print each number and all these processors had been produced during the last 1000 years, still: 1e1000 / (80e9 - 1000 - 8.4e9 - 1000) > 1e973 seconds to print all the numbers. That is 10e956 billion years."
Anyway, if you wish wait:
BigInteger n = BigInteger.ONE;
BigInteger last = BigInteger.TEN.pow(1000);
while(n.compareTo(last) < 0) {
System.out.println(n);
n = n.add(BigInteger.ONE);
}
Assuming only System.out.print is able to use (String is a library, see [3]), a possible solution without copy over and over again strings, and with the expected output could be:
static void printDigits(int n) {
ds(0, n, new byte[n]);
}
static void ds(int p, int k, byte[] d) {
if (p < d.length) { // if more digits to print
for (byte i = 0; i < 10; i++) { // from digit 0 to 9
d[p] = i; // set at this position
ds(p + 1, i == 0 ? k : (p < k ? p : k), d); // populate next storing first non-zero
}
} else {
if(k < d.length) { // if is not zero
if(k < d.length - 1 || d[d.length - 1] != 1) // if is not one
System.out.print(", "); // print separator
for(int i = k; i < d.length; i++) // for each digit
System.out.print((char)('0' + d[i])); // print
}
}
}
then, for printDigits(5) the output is
1, 2, 3, 4, ..., 99999
[1] https://epsnews.com/2020/09/14/total-microprocessor-sales-to-edge-slightly-higher-in-2020/
[2] https://en.wikipedia.org/wiki/Clock_rate
[3] https://docs.oracle.com/javase/7/docs/api/java/lang/String.html
Using recursion (if only to print):
void digits(int count) {
if (count < 0) throw new IllegalArgumentException("invalid count: " + count);
digits(count, "");
}
void digits(int count, String text) {
if (count == 0) {
System.out.println(text);
} else {
for (var i = 0; i < 10; i++) {
if (i == 0 && text.isEmpty()) {
digits(count-1, text);
} else {
digits(count-1, text+i);
}
}
}
}
Write a program to produce the following output for any given integer number between
1 and 9 inclusive.
Enter an integer value [1..9]: 6
1
12
123
1234
12345
123456
666666
66666
6666
666
66
6
I have done the top half but I can not figure out the bottom with the repeating user input.
package lab7;
import java.util.Scanner;
public class problem5 {
public static void main(String[] args) {
Scanner scan = new Scanner (System.in);
System.out.println("Input an integer between 1 and 9");
int input = scan.nextInt();
while (input <= 9) {
for (int i = 1; i <= input; i++) {
for (int j = 1; j <= i; j++) {
System.out.print(j);
}
System.out.println();
}
break;
}
}
}
Expected result: included at the top; actual result so far (input of 5):
1
12
123
1234
12345
You're pretty close. You have a for loop that covers the first half of the output you want. You can add a second for loop to handle the second half of the output.
This is pretty similar to the first loop, but has a few small differences:
instead of the loop variable starting at 1 and increasing, this one starts at input and decreases each time through (i-- instead of i++)
instead of printing any of the loop variables (i or j), it prints the input value ("6" in your example)
for (int i = input; i > 0; i--) {
for (int j = 1; j <= i; j++) {
System.out.print(input);
}
System.out.println();
}
If I run that code locally – so your for loop, then this for loop, then the break statement – this is the output:
Input an integer between 1 and 9
6
1
12
123
1234
12345
123456
666666
66666
6666
666
66
6
I would prefer a more efficient algorithm, your current approach is O(n2); consider the digits '1' - '9'; if we store them in a String then we can take a simple substring of that String for each line at the top (for example, "123456789".substring(0, 3) -> "123") that can be used to generate the top through successive calls to substring. We can use a similar approach to build the bottom; use an array of all possible rows and iteratively call substring. Finally, don't forget to validate that input is between one and nine inclusive. Something like,
Scanner scan = new Scanner(System.in);
String digits = "123456789";
String[] btm = { "1", "22", "333", "4444", "55555",
"666666", "7777777", "88888888", "999999999" };
System.out.println("Input an integer between 1 and 9");
int input = scan.nextInt();
if (input < 1 || input > 9) {
System.err.printf("Invalid input: %d%n", input);
System.exit(1);
}
for (int i = 0; i < input; i++) {
System.out.println(digits.substring(0, i + 1));
}
for (int i = input - 1; i >= 0; i--) {
System.out.println(btm[input - 1].substring(0, i + 1));
}
This is the question we were assigned :
Nine coins are placed in a 3x3 matrix with some face up and some face down. You can represent the state of the coins using a 3x3 matrix with values 0 (heads) and 1 (tails). Here are some examples:
0 0 0 1 0 1 1 1 0
0 1 0 0 0 1 1 0 0
0 0 0 1 0 0 0 0 1
Each state can also be represented using a binary number. For example, the preceding matrices correspond to the numbers:
000010000 101001100 110100001
There are a total of 512 possibilities, so you can use decimal numbers 0, 1, 2, 3,...,511 to represent all the states of the matrix.
Write a program that prompts the user to enter a number between 0 and 511 and displays the corresponding matrix with the characters H and T.
I want the method toBinary() to fill the array binaryNumbers. I realized that this does not fill in 0s to the left. I have to think that through but is that the only thing that is the problem?
//https://www.geeksforgeeks.org/java-program-for-decimal-to-binary-conversion/
import java.util.Scanner;
public class HeadsAndTails {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int num = input.nextInt();
int[] binaryNumbers = toBinary(num);
for (int i = 0; i < 9; i++) {
printArr(binaryNumbers);
System.out.print(binaryNumbers[1]);
}
}
public static int[] toBinary(int inputtedNumber) {
int[] binaryNum = new int[9];
int i = 0;
while (inputtedNumber > 0) {
binaryNum[i] = inputtedNumber % 2;
inputtedNumber = inputtedNumber/2;
inputtedNumber++;
} return binaryNum;
}
public static void printArr(int[] arr) {
for (int i = 0; i < 9; i++) {
if (arr[i] == 0) {
System.out.print("H ");
} else {
System.out.print("T ");
}
if (arr[i+1] % 3 == 0) {
System.out.println();
} System.out.print(arr[i]);
}
}
}
Looks like you are incrementing the wrong variable in your while loop:
while (inputtedNumber > 0) {
binaryNum[i] = inputtedNumber % 2;
inputtedNumber = inputtedNumber/2;
i++; // NOT inputtedNumber
} return binaryNum;
Also note, a new int[9] is probably already initialized to 0, but if not, you could just loop 9 times, rather than until the inputtedNumber is 0:
for (int i = 0; i < 9; i++) {
binaryNum[i] = inputtedNumber % 2;
inputtedNumber = inputtedNumber/2;
}
return binaryNum;
Finally, I think your array might be backwards when you're done, so you may need to reverse it or output it in reverse order
I realize this is a homework assignment so you should stick with your current approach. However, sometimes it can be fun to see what can be achieved using the built in features of Java.
The Integer class has a method toBinaryString that's a good starting point:
int n = 23;
String s1 = Integer.toBinaryString(n);
System.out.println(s1);
Output: 10111
But as we can see, this omits leading 0s. We can get these back by making sure our number has a significant digit in the 10th place, using a little bit-twiddling:
String s2 = Integer.toBinaryString(1<<9 | n);
System.out.println(s2);
Output: 1000010111
But now we have a leading 1 that we don't want. We'll strip this off using String.substring, and while we're at it we'll use String.replace to replace 0 with H and 1 with T:
String s3 = Integer.toBinaryString(1<<9 | n).substring(1).replace('0','H').replace('1','T');
System.out.println(s3);
Output: HHHHTHTTT
Now we can print this string in matrix form, again using substring to extract each line and replaceAll to insert the desired spaces:
for(int i=0; i<9; i+=3)
System.out.println(s3.substring(i, i+3).replaceAll("", " ").trim());
Output:
H H H
H T H
T T T
If we're up for a bit of regex wizardry (found here and here) we can do even better:
for(String sl : s3.split("(?<=\\G.{3})"))
System.out.println(sl.replaceAll(".(?=.)", "$0 "));
Putting it all together we get:
int n = 23;
String s3 = Integer.toBinaryString(1<<9 | n).substring(1).replace('0','H').replace('1','T');
for(String s : s3.split("(?<=\\G.{3})"))
System.out.println(s.replaceAll(".(?=.)", "$0 "));
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));
I am new to Programming so bear with me if I do not properly present my issue. I have an assignment to create a program to assign integer values 1-25 to a 25 element integer array. I need to print the array as five separate lines with each line containing 5 elements separated by commas. The last element does not have a comma following it. The final output should be as follows:
1,2,3,4,5
6,7,8,9,10
11,12,13,14,15
16,17,18,19,20
21,22,23,24,25
The code that I came up with comes close, but it's not quite right. The code that I came up with is:
public class Test2 {
/**
* #param args
* the command line arguments
*/
public static void main(String[] args) {
int[] numbers = new int[25];
for (int i = 0; i < numbers.length; i++) {
numbers[i] = i + 1;
System.out.print(numbers[i] + ",");
if (i % 5 == 0 && i > 0)
System.out.println();
}
}
}
The printout that I get from my code is as follows:
1,2,3,4,5,6,
7,8,9,10,11,
12,13,14,15,16,
17,18,19,20,21,
22,23,24,25,
I am not sure why I am getting 1-6 on the first line as well as how to remove the comma at the end of each line. Any help pointing out my errors would be appreciated.
The error is that you are checking if int i is divisible by 5 (i % 5), not numbers[i] (numbers[i] % 5). This way, your code prints:
number 1 when i = 0,
number 2 when i = 1,
number 3 when i = 2,
number 4 when i = 3,
number 5 when i = 4,
number 6 when i = 5
and finally prints line break.
The correct code is:
int[] numbers = new int[25];
for (int i = 0; i < numbers.length; i++) {
numbers[i]=i+1;
System.out.print(numbers[i]);
if (numbers[i] % 5 == 0 && i > 0) {
System.out.println();
} else {
System.out.print(",");
}
}
The above code will print (as intended):
1,2,3,4,5
6,7,8,9,10
11,12,13,14,15
16,17,18,19,20
21,22,23,24,25
You're getting 6 numbers on the first line, because you start counting at i=0, and only print the newline once i=5; at which point the number you've just printed is 6, not 5 - you're printing i+1 in each iteration.
If you made your logic such that it printed EITHER a comma OR a newline but not both, you'd get rid of the commas at the ends of the lines.
You're close. Very close.
Consider what your condition is checking - you want to inspect a value i, and want to stop when that particular value is divisible by 5 but is nonzero.
The problem is that you have the wrong value - i isn't what you want, but numbers[i]. The reason: each number in numbers[i] is offset of i by 1.
What you want to do is check if numbers[i] is divisible by 5. You still need to check for a nonzero i, though.
if(numbers[i] % 5 == 0 && i > 0) {
System.out.println(numbers[i]);
} else {
System.out.print(numbers[i] + ",");
}
Replace
if (i % 5 == 0 && i > 0)
with
if (i % 5 == 4)