Inserting dashes between two odd numbers - java

folks. In my program I take a user input of numbers of a String type and put dashes between two odd numbers. For example:
Input = 99946 Output = 9-9-946
Input = 56730 Output = 567-30
But in my code, if I, for example, write 9933444 then the ouput that I'm getting is: 9-9-9-3-3-3-344444. It correctly separates the odd numbers by dashes but also adds extra numbers. What could be causing this bug ?
import java.util.Arrays;
import java.util.Scanner;
public class DashInsert {
public static void main(String[] args)
{
Scanner kbd = new Scanner(System.in);
System.out.println("Enter the numbers: ");
String myString = kbd.nextLine();
char[] numbers = myString.toCharArray();
String result = "";
for(int i = 1; i < numbers.length; i++)
{
int value1 = Character.getNumericValue(numbers[i]);
int value2 = Character.getNumericValue(numbers[i-1]);
if(value1 % 2 != 0 && value2 % 2 != 0)
{
result += numbers[i-1] + "-" + numbers[i] + "-";
}
else
result += numbers[i-1] + "" + numbers[i];
}
System.out.println(result);
}
}

There is a trivial one-line solution:
str = str.replaceAll("(?<=[13579])(?=[13579])", "-");
This works by matching between odd numbers and replacing the (zero-width) match with a dash. The regex is a look behind and a look ahead.
It can be done without look arounds by capturing the odd digits and putting them back using a back reference:
str = str.replaceAll("([13579])([13579])", "$1-$2");
Both solutions achieve the same result.

The code can be simplified a bit (as well as solve the "double char" bug):
String str = "9933444";
char[] numbers = str.toCharArray();
String result = "";
for(int i = 1; i < numbers.length; i++)
{
int value1 = Character.getNumericValue(numbers[i-1]);
int value2 = Character.getNumericValue(numbers[i]);
result += value1;
if(value1 % 2 != 0 && value2 % 2 != 0) {
result += "-";
}
}
result += numbers[numbers.length - 1];
System.out.println(result);
OUTPUT
9-9-3-3444
The reason for the "double char" bug is that every loop prints both the items on the places i-1 and i. which means that i will be printed again on the next loop (where it will become i-1).
In case you're using Java 8 - you can use a Stream do something that looks more like what you were originally trying to do:
public static void main(String[] args){
String str = "9933444";
List<String> lst = Arrays.asList(str.split(""));
String res = lst.stream().reduce((a,b) -> {
if (isOdd(a) && isOdd(b)) {
return a + "-" + b;
}
else {
return a + b;
}
}).get();
System.out.println(res);
}
// grep the last digit from the string and check if it's odd/even
public static boolean isOdd(String x) {
if (x.length() > 1) {
if (x.substring(x.length()-1).equals("-")) {
x = x.substring(x.length()-3, x.length()-2);
}
else {
x = x.substring(x.length() - 1);
}
}
return Integer.parseInt(x) % 2 == 1;
}
OUTPUT
9-9-3-3444

The bug is caused by the fact that, even though you are looping through your list of numbers one at a time, you write out two numbers with each loop iteration. Logically, this design will always yield repeated numbers.
Either change your loop to iterate by twos, or print a single number in each loop iteration.

Don't bother concatenating two odd numbers with the "-" in between them, during the evaluation, just add the "-" after the number that you're checking in each iteration.
public static void main(String[] args) throws Exception {
Scanner kbd = new Scanner(System.in);
System.out.println("Enter the numbers: ");
String myString = kbd.nextLine();
char[] numbers = myString.toCharArray();
String result = "";
for(int i = 0; i < numbers.length; i++) {
int value1 = Character.getNumericValue(numbers[i]);
int value2 = i + 1 < numbers.length
? Character.getNumericValue(numbers[i + 1])
: 0;
if(value1 % 2 != 0 && value2 % 2 != 0) {
result += numbers[i] + "-";
} else {
result += numbers[i];
}
}
System.out.println(result);
}
Results:
Input: 99946 Output: 9-9-946
Input: 56730 Output: 567-30
Input: 9933444 Output: 9-9-3-3444

Related

how to remove the comma at the end [duplicate]

This question already has answers here:
Avoid printing the last comma
(13 answers)
Closed 1 year ago.
I'm writing a simple java code that takes two integers as min and max and a third integer as divisor and it finds all numbers between that are divisible by the third integer, which worked fine but in the output I can't get rid of the last comma.
Scanner scanner = new Scanner(System.in);
System.out.print("Enter the first number: ");
int a = scanner.nextInt();
System.out.print("Enter the second number: ");
int b = scanner.nextInt();
System.out.print("Enter the divisor: ");
int d = scanner.nextInt();
for(int i=a; i<=b; i++) {
if(i%d == 0)
System.out.print(i+", ");
}
How could I do it?
I prefer to avoid the issue by writing commas before things where appropriate, and not after. It seems more straightforward to know when you're doing the first thing, compared to knowing when you're doing the last thing.
String sep = ""; // no separator before first print
for (int i=a; i<=b; i++) {
if (i%d == 0) {
System.out.print(sep + i);
sep = ", "; // separator for every following print
}
}
You can use an if statement to print a comma only if it is not the last element.
if(i%d == 0){
System.out.print(i);
if(((i/d)+1)*d <= b) System.out.print(", ");
}
For these kinds of problems the StringJoiner is especially useful:
StringJoiner out = new StringJoiner(",");
for(int i=a; i<=b; i++) {
if(i%d == 0)
out.add(Integer.toString(i));
}
System.out.println(out);
You can use as boolean to control printing the comma.
boolean addComma = false;
for (int i=a; i<=b; i++) {
if (i%d == 0) {
System.out.print((v ? "," : "") + i);
addComma = true;
}
}
You could use substringto strip the space and comma off the end if it is the last number. It is not as elegant as Unmitigated's solution, but it should work:
String validNumbers = "";
for(int i=a; i<=b; i++) {
if(i%d == 0)
validNumbers += i + ", ";
}
if (validNumbers != "") {
validNumbers = validNumbers.substring(0, validNumbers.length() - 2);
}
System.out.print(validNumbers);

Removing negative sign from a string

I have to reverse the string a user inputs and I'm trying to remove the negative sign when a user enters a negative number but I'm unsure of how to go about this.
I've tried using string.replace() but I instead of printing for example "9" when a user entered "-9", it would return "99-9"
import java.util.Scanner;
public class Reverse {
public static void main(String[] args) {
Scanner scnr = new Scanner (System.in);
System.out.println("Type a number: ");
String num = scnr.nextLine();
String reverse = "";
for (int i = num.length() - 1; i >= 0; i--) {
reverse = reverse + num.charAt(i);
}
System.out.println("Reverse is: " + reverse);
}
}
The straight forward solution: put an if block in your loop!
You are right now adding characters unconditionally. You could for example only append characters that are digits. Then any other thing, like a '-' won't show up in your output!
You can try something like this.
public class App {
public static void main(String[] args) {
String input = "78-889-969-*)(963====";
StringBuilder builder = new StringBuilder();
for (int i = input.length() - 1; i >= 0; i--) {
if (input.charAt(i) >= 48 && input.charAt(i) <= 57) {
builder.append(input.charAt(i));
}
}
System.out.println("builder = " + builder.toString());
}
}
Using Character.isDigit()
public class App {
public static void main(String[] args) {
String input = "78-889-969-*)(963====";
StringBuilder builder = new StringBuilder();
for (int i = input.length() - 1; i >= 0; i--) {
if (Character.isDigit(input.charAt(i))) {
builder.append(input.charAt(i));
}
}
System.out.println("builder = " + builder.toString());
}
}
Replace the for loop with the below.
for (int i = num.length() - 1; i >= 0; i--)
{
if(num.charAt(i) == 45){
break;
}
reverse = reverse + num.charAt(i);
}`
45 is the ASCII value of - sign. The if(num.charAt(i) == 45) checks if there is - sign and if so it breaks the loop before it prints the - sign.
Note - The loop will not break till it reaches i = 0.

String of only even numbers and only odd numbers

I know there are already questions asking something similar to my question, but despite reading those, they don't quite do what I want.
I am creating a code that takes a users input of a number between 0-100 (inclusive). Whatever the number, it will print all the numbers leading up to that number and that number
EX: user input = 25
output = 012345678910111213141516171819202122232425
I have that part working. Now I am supposed to use that string and create two new strings, one for only the odd and the other one for the even numbers.
EX: user input = 25
output: odd numbers: 135791113151719212325 & even numbers = 024681012141618202224
Here is my code so far:
import java.util.Scanner;
public class OddAndEven{
public String quantityToString() {
Scanner number = new Scanner(System.in);
int n = number.nextInt();
String allNums = "";
if ((n >= 0) && (n <= 100)) {
for (int i = 0;i <= n; ++i)
allNums = allNums + i;
return allNums;
}
else {
return "";
}
}
public void oddAndEvenNumbers(int num) {//Start of second method
String allNums = ""; //String that quantityToString returns
String odd = "";
String even = "";
if ((num >= 0) && (num < 10)) { //Looks at only single digit numbers
for (int i = 0; i <= allNums.length(); i++) {
if (Integer.parseInt(allNums.charAt(i))%2 == 0) { //trying to get the allNums string to be broken into individual numbers to evaluate
even = even + allNums.charAt(i); //adding the even numbers of the string
}
else {
odd = odd + allNums.charAt(i);
}
}
}
else { //supposed to handle numbers with double digits
for (int i = 10; i <= allNums.length(); i = i + 2) {
if (Integer.parseInt(allNums.charAt(i))%2 == 0) {
even = even + allNums.charAt(i);
}
else {
odd = odd + allNums.charAt(i);
}
}
}
System.out.println("Odd Numbers: " + odd);
System.out.println("Even Numbers: " + even);
}
public static void main(String[] args) {
System.out.println(new OddAndEven().quantityToString());
//System.out.println(new OddAndEven().oddAndEvenNumbers(allNums));
//Testing
OddAndEven obj = new OddAndEven();
System.out.println("Testing n = 5");
obj.oddAndEvenNumbers(5);
System.out.println("Testing n = 99");
obj.oddAndEvenNumbers(99);
I know my problem is at the part when its supposed to take the string apart and evaluate the individual numbers, but I don't know what to do. (I've also tried substring() & trim()) Also I have not learned how to use arrays yet, so that is why I did not try to use an array.
I think you can make it that way:
int x = 20;
StringBuilder evenNumberStringBuilder = new StringBuilder();
StringBuilder oddNumberStringBuilder = new StringBuilder();
for(int i =0 ; i<x+1; i++){
if(i % 2 == 0)evenNumberStringBuilder.append(i);
else oddNumberStringBuilder.append(i);
}
System.out.println(evenNumberStringBuilder);
System.out.println(oddNumberStringBuilder);
Output:
02468101214161820
135791113151719
you are already taking the input as integer, so don't work with strings. I recommend that to use this loop;
Scanner number = new Scanner(System.in);
System.out.print("Even Numbers: ");
for (int i = 0; i <= number; i=i+2) {
System.out.print(i);
}
System.out.println("");
System.out.print("Odd Numbers: ");
for (int i = 1; i <= number; i=i+2) {
System.out.print(i);
}
You can simply evaluate numbers while storing them in an allnumbers string, here's a functioning code:
int x = 23; //user input
String s=""; //contains all numbers from 0 to userinput
String odd =""; //contains all odd numbers from 0 to userinput
String even = ""; //contains all even numbers from 0 to userinput
for(int i = 0 ; i< x+1 ; i++){
s += i;
if(i%2==0) //if i is an even number
even += i;
else //if i is an odd number
odd += i;
}
System.out.println(s); //displaying all numbers from 0 to user input
System.out.println(odd); //displaying odd numbers from 0 to user input
System.out.println(even); //displaying even numbers from 0 to user input

Last word/sentence on an Array Java

I have an assignment, it looks pretty easy however I cannot figure it out how to solve it.
It says:
a) Ask the user: How many words/sentences do you want to write (at
least 5) ? (Use while loop)
b) Use for loop to make the user write the words/sentences
c) After the user's written the words/sentences, output which
word/sentence comes last alphabetically (using .compareTo() method )
This is what I came up with:
import java.util.Scanner;
import java.lang.String;
import java.util.Arrays;
public class LastString {
public static void main (String [] args){
Scanner input = new Scanner (System.in);
final short MIN_NUM = 2;
int num = 0;
int count = 0;
String [] sentence = new String [0];
String last = "";
while (num < MIN_NUM){
System.out.println("How many words/sentences do you want to put? " + "\t\t\t\t\t\t\t\t --- at least " + MIN_NUM);
num = input.nextInt();
sentence = new String [num];
}
for (int i = 0; i < num ; i++ ) {
System.out.println("\nWrite a word/sentence" + "\t\t\t\t\t\t\t\t\t --- (Time: " + (i+1) + " )");
sentence [i] = input.nextLine();
System.out.println("The word/sentence is: " + sentence[i]);
}
int i = 0;
int max;
for (i=0;i<num-1 ;i++ ) {
if(sentence[i].compareTo(sentence[i+1]) > 0){
last = sentence[i];
count ++;
}else if (sentence[i].compareTo(sentence[i+1]) < 0) {
last = sentence[i+1];
count++;
}
}
System.out.println("\n\n------------" +
"\nLast word/sentence is: " + last);
System.out.println(Arrays.toString(sentence));
}
}
I compiles and runs. I have two problems:
nextLine >>> it is skiping the first Sentence
I don't know how to make the algorithm to calculate which word/sentence has the biggest value or, using the compareTo() method which word/sentence has the value > 0 compared to each and every other value on the array.
Thank you.
Answer to Q1 : num = input.nextInt(); takes a number as the input but doesn't also consume the new-line, and hence the nextLine consumes the empty new line ... you could use input.nextLine also to get the first number instead of num = input.nextInt(); by reading a line, then parsing the int value as num = Integer.parseInt(input.nextLine());
Answer to Q2 :
You re-set the value of last everytime but you don't compare the value of the next biggest candidate with the last before re-assigning last ...
for example, look at the following :
for (int i = 0; i < num - 1; i++) {
String thisLast = "";
if (sentence[i].compareTo(sentence[i + 1]) > 0) {
thisLast = sentence[i];
count++;
} else if (sentence[i].compareTo(sentence[i + 1]) < 0) {
thisLast = sentence[i + 1];
count++;
}
if (thisLast.compareTo(last) > 0)
last = thisLast;
}
it will solve your problem....
int count = 0;
String [] sentence = new String[6];
String last = "";
for (int i = 0; i < num ; i++ ) {
System.out.println("\nWrite a word/sentence" + "\t\t\t\t\t\t\t\t\t --- (Time: " + (i+1) + " )");
sentence [i] = input.nextLine();
count++;
if(count >= 2){
if(sentence[i].compareTo(last) > 0){
last = sentence [i] ;
}
}else{
last = sentence [i];
}
System.out.println("The word/sentence is: " + sentence[i]);
}

Can't locate Java substring in for loop

I'm trying to make a calculator app and I have a string for the final equation inputted.
"983+388+12"
How I'm solving is by first identifying where the operator is. After this I loop backwards and forwards trying to find the 2 numbers and then I add them. So I would find the plus symbol then 983 and 388 and add them. I'm having trouble matching the previous/next numbers in relation to the add symbol.
public static void main(String[] args)
{
int plus=0;
String string="983+388+12";
//locating Plus symbol
for(int i=0;i<string.length();i++)
{
if(string.charAt(i)=='+')
{
plus=i;
}
}
//locating next number (should be 388)
for(int i=plus+1;i<string.length();i++)
{
if(string.charAt(i)=='+' || string.charAt(i)=='-')
{
String nextNumber=string.substring(plus+1, i-1);
System.out.println(nextNumber);
break;
}
}
I am not getting anything returned as a value for nextNumber
When you find the + in the first loop, you don't stop scanning the string. This results in plus marking the location of the last +, which is after the 388 and before the 12. The second loop never finds a + or a - after the last +, so nothing is ever printed. When you find the first +, break out of the loop.
Also, to avoid just 38 being found, correct your substring call, where the ending index is exclusive.
String nextNumber = string.substring(plus + 1, i);
Try using only one loop, see below (working example). I didn't break anything up into smaller methods.
public static void main(String[] args) {
String string="983+388+12";
String numberStr="0";
int lastSignPos = 0;
int signPos=0;
char sign = '+';
int total=0;
//locating Plus symbol
for(int i=0; i < string.length(); i++) {
if(string.charAt(i)=='+' || string.charAt(i)=='-') {
lastSignPos = signPos;
signPos = i;
numberStr = "0";
if (lastSignPos == 0){
// first number in series
numberStr = string.substring(0,signPos);
} else {
numberStr = string.substring(lastSignPos + 1, signPos);
}
sign = '+';
if (string.charAt(lastSignPos)=='-'){
sign = '-';
}
total += Integer.parseInt(sign + numberStr);
}
}
// take care last number
numberStr = string.substring(signPos+1);
sign = '+';
if (string.charAt(signPos)=='-'){
sign = '-';
}
total += Integer.parseInt(sign + numberStr);
System.out.println(total);
}
You can try something like this :
String example = "123+456+678";
String delim = "+";
StringTokenizer st = new StringTokenizer(example,delim);
while (st.hasMoreElements()) {
System.out.println("StringTokenizer Output: " + st.nextElement());
}

Categories

Resources