I am trying to write a program to determine the sum of the digits in a string using recursion, I thought that the following code would print "The sum is 6" to the console but instead it outputs "The code is 150".
Could someone please tell me what my mistake is?
public class SumOfString {
public static String Test = new String();
public static Integer count = new Integer(0);
public static Integer sum = new Integer(0);
public static long sumThis(String s){
if (count< s.length()){
if (Character.isDigit(s.charAt(count))){
int digit = s.charAt(count);
count++;
sum += digit;
return sumThis(s);}
else{
count++;
return sumThis(s);}}
else{
return sum;}}
public static void main(String[] args) {
Test= "1a2b3c";
System.out.println("The sum is " + sumThis(Test));
}
Without solving the problem for you:
One bug in your code is :
int digit = s.charAt(count);
Test this snippet of code on the String "1" with a count of 0. It does not return the integer 1. To get that, you need to wrap this call :
Character.getNumericValue(s.charAt(count));
You should really get in the habit of running your code in the debugger.
Have a look at a ascii table as you will see that the value of "1" is 49, "2" is 50 and "3" is 51 summing to 150
try
int digit = s.charAt(count) - 48;
The cause of this is the line at
int digit = s.charAt(count);,
charAt will return a character primitive therefore it will be the decimal value of that character.
Character = Decimal Value
`1` = 49
`2` = 50
`3` = 51
-------
150
You need to convert the character to int: Java: parse int value from a char
Related
Suppose you code a simple divide program in Java and run it. Now suppose it gives you this answer 451.12531 . But you want to select only a single or two digit from this answer may be before the point or after it. In this case we assume that we need to select. Second number which is 5. And you want to print this only. How do you do that?
This can be done by converting your Double to a String using:
String s = String.valueOf(double);
You can then use the Character.getNumericValue() method to get the desired number/position:
int x = Character.getNumericValue(s.charAt(1));
Full example:
Double d = 451.12531;
String s = String.valueOf(d);
int x = Character.getNumericValue(s.charAt(1));
where x is your desired number, in the above example it will be 5
Try this :
private void selectSingleDigit(double number) {
String noInStringFormat = String.valueOf(number);
int digit = getDigitAtSpecificDigit(2,noInStringFormat);
System.out.println(digit);
}
private int getDigitAtSpecificDigit(int index,String str){
if (str != null && !str.isEmpty()) {
return Integer.parseInt(String.valueOf(str.charAt(index)));
} else return -1;
}
Try using this, here d1 will have digits before decimal point and d2 will have digits after decimal point.
String d1 = text.substring( 0,text.indexOf('.'))
String d2 = text.substring( text.indexOf('.'), text.length());
I am suppose to find odd numbers in an integer for HW. So countOddigtis(56781) should return( NOT PRINT ) 5 7 1. My approach was to convert the integer into a string and use that to return. Problems I am having are
Missing return statement error, even though I have a return statement in the if statement. Can someone explain what this error means and how to get past it?
It prints the wrong answer 49 for 56781 when I put return x; at the end of the method.
Can Java solve
stringn.charAt(x) % 2 != 0 considering I am might(NOT SURE) be comparing a string or char with an int?
P.S keep it simple, I don't much Java, I just started.
int countOddigits( int n )
{
int x = 0;
String stringn = Integer.toString(n);
while ( x <= stringn.length() - 1 )
{
if ( stringn.charAt(x) % 2 != 0 )
{
return stringn.charAt(x);
}
x++;
}
}
public void run()
{
System.out.printf("Odd number is %d\n: ", countOddigits(567981) );
}
You presumably don't want to return immediately when you find the first odd digit. You also need to convert the result back into an int (to match your return type). You can parse it with Integer.parseInt(String); and you can build that String with a StringBuilder. Also, you could make the method static. Like,
static int countOddDigits(int i) { // <-- camel case, that is camelCase
StringBuilder sb = new StringBuilder();
// for each char ch in the String form of i converted to a character array
for (char ch : String.valueOf(i).toCharArray()) {
if (Character.digit(ch, 10) % 2 != 0) {
sb.append(ch);
}
}
return Integer.parseInt(sb.toString());
}
Then, to test it, you can call it like
public static void main(String[] args) {
int oddDigits = countOddDigits(56781);
System.out.println(oddDigits);
}
Which outputs
571
public class WordScrambleEx1 {
public static void main(String[] args) {
String[] strArr = {"CHANGE", "LOVE", "HOPE", "VIEW"};
String answer = getAnswer(strArr);
String question = getScrambledWord(answer);
System.out.println("Question :" + question);
System.out.println("Answer: " + answer);
}
public static String getAnswer(String[] strArr) {
String i = strArr[(int)Math.random()*4];
return i;
}
public static String getScrambledWord(String str) {
char[] character = str.toCharArray();
String question1 = null;
for(int i = 0; i < character.length; i ++)
{
char[] java = new char [(int)Math.random()*i] ;
question1 = new String(java);
}
return question1;
}
}
I am very new to Java and was given a question where I am given four letters of words and my method needs to pick one of them randomly using Math.random and scramble the characters of that string.
My code finds a String from the given array but does not scramble the string. Can anyone tell me what I am doing wrong?
Understanding constructor and scope is really hard.
first mistake:
(int) Math.random() * i
will always return 0, because Math.random() returns a float between 0 and 1, so it will always be zero when you cast it to int (int doesnt round, it just cuts off the numbers after the comma).
you can fix this by using this:
(int) (Math.random() * i)
now we are first multiplying the float result of Math.random() with i which results in a float because the first number is a float. then we are casting this float to an int.
second mistake:
public static String getScrambledWord(String str) {
char[] character = str.toCharArray();
String question1 = null;
for(int i = 0; i < character.length; i ++)
{
char[] java = new char [(int)Math.random()*i] ;
question1 = new String(java);
}
return question1;
}
each iteration you create a new char array with a length of 0 and then you set question1 to it, which is always an empty string because the java array has nothing in it.
i would do it as follows:
public static String getScrambledWord(String str) {
char[] character = str.toCharArray();
String question1 = new String();
ArrayList<Character> chars = new ArrayList<Character>(); //an arraylist is an array wich dynamically changes its size depending on the amount of its elements
for (int i = 0; i < character.length; i++) {// first we put all characters of the word into that arraylist
chars.add(character[i]);
}
while(chars.size()>0){//then we iterate over the arraylist as long as it has more than 0 elements
int index = (int)(Math.random() * chars.size());//we create a random index in the range of 0 and the arraylists size
question1 += chars.get(index);// we add the letter at the index we generated to the scrambled word variable
chars.remove(index);// then we remove the character we just added to the scrambled word, from the arraylist, so it cant be in there twice
}// thus the size decreases by 1 each iteration until every element of the arrraylist is somewhere in the scrambled word
return question1;
}
There are some mistakes in your code. The way you generate random integers is misleading. Let's look at the statement (int)Math.random() * 4 for an explanation. Math.random() does:
Returns a double value with a positive sign, greater than or equal to 0.0 and less than 1.0.
Now, in Java a type cast has precedence over +, -, * and /, so what actually happens is ((int)Math.random()) * 4. Math.random() returns a floating point number between 0.0 and 1.0 exclusive, so roughly [0.0, 0.999999...]. A cast to int will truncate all decimal places and you will always get 0. Your statement then simplifies to 0 * 4 = 0. Overall, you always get the first word.
I recommend you to use the Random class instead. It provides a method nextInt(int n), which returns a random integer between 0 inclusive and n exclusive, so [0, n - 1].
Since there are a lot of errors in your code, I would like to provide you this solution:
import java.util.Random;
public class WordScrambleEx1 {
private static Random random;
public static void main(String[] args) {
// Create object of class (initializes the
// random generator with a default seed)
random = new Random();
String[] strArr = { "CHANGE", "LOVE", "HOPE", "VIEW" };
String answer = getAnswer(strArr);
String question = getScrambledWord(answer);
System.out.println("Question: " + question);
System.out.println("Answer: " + answer);
}
public static String getAnswer(String[] strArr) {
// Chooses a random index in [0, strArr.length - 1]
int index = random.nextInt(strArr.length);
String i = strArr[index];
return i;
}
public static String getScrambledWord(String str) {
String remaining = str;
String scrambled = "";
// Loop over the string, each time choose a random letter
// and add it to the scrambled word, then remove that letter
// from the remaining word. Repeat until all letters are gone.
for (int i = str.length(); i > 0; i--) {
// Choose the index of a letter in the remaining string
int index = random.nextInt(remaining.length());
// Add the letter at the random index to your scambled word
scrambled += remaining.charAt(index);
// Remove the chosen character from the remaining sequence
remaining = remaining.substring(0, index) + remaining.substring(index + 1);
}
return scrambled;
}
}
A sample input of 12345 should return 12,345. I have it figured out i think. Only problem is the string I get is reversed (543,21). Now i know there's ways to reverse a string pretty easily but that's more complexity to the running time so I was wondering if there was a straightforward way to do it within the auxiliary itself?
public void print(int n){
String number = Integer.toString(n);
StringBuilder answer = new StringBuilder();
if(number.length() > 3){ //Only worry about adding commas if its more than three digits
printAux(number, answer, 1, number.length()-1);
System.out.println(answer);
}
}
private void printAux(String s, StringBuilder answer, int count, int index){
if(index < 0){
return;
}
else{
//If the counter is at the 4th index meaning it has passed three digits
if(count%3 == 1 && count > 3){
answer.append(",");
index = index + 1;
count = 0;
}
else{
answer.append(s.charAt(index));
}
printAux(s, answer, count + 1, index - 1);
}
}
Something simpler
public static void print(String s) {
out.print(s.charAt(0));
if (s.length() == 1) out.print("\n");
else {
if (((s.length()-1) % 3) == 0) out.print(",");
print(s.substring(1));
}
}
Explanation:
always print the 1st character
if there is no more character, print CR
if there is at least one character to process, check if the length of what to process is a multiple of 3, if yes print a ","
and call recursively print with the string minus the 1st character
You can can use StringBuilder.reverse() to reverse a String in one line like
String str = "abc";
str = new StringBuilder(str).reverse().toString();
But you could also use printf1. Something like,
public static void print(int n) {
System.out.printf("%,d%n", n);
}
public static void main(String[] args) {
int num = 123456789;
print(num);
}
Output is (as requested)
123,456,789
1See also The Java Tutorials - Formatting Numeric Print Output for more options.
You can use the following DecimalFormat to get the job done.
String number = "1000500000.574";
double amount = Double.parseDouble(number);
DecimalFormat formatter = new DecimalFormat("#,###.00");
System.out.println(formatter.format(amount));
I'm trying to create a program that reads in two bases from stdin and checks to see what's the smallest number in which both have repeating digits in it. It seems to be working fine for small bases but when I use larger bases I seem to be getting the wrong answer. e.g. giving it 3 and 50 it will find 22 as the smallest number where they both have repeated digits but i'm pretty sure 22 in base 50 is a single number.
What's the logic here that I'm missing? I'm stumped. Anything to point me in the right direction would be appreciated :)
My conversion method, this works for smaller bases but not larger it seems.
public static String converties(int number, int base)
{
int remainder;
ArrayList<Integer>remainders = new ArrayList<Integer>();
while (number != 0)
{
remainder = number%base;
remainders.add(remainder);
number = number/base;
}
String result = "";
for (int i = 0; i < remainders.size(); i++)
{
result+=Integer.toString(remainders.get(i));
}
result = reverseString(result);
return result;
}
public static String reverseString(String result)
{
String newResult = "";
for (int i = result.length()-1; i >= 0; i--)
{
newResult+=result.charAt(i);
}
return newResult;
}
public static boolean areThereRepeats(String value)
{
ArrayList<Character> splitString = new ArrayList<Character>();
for (char c : value.toCharArray())
{
//if it already contains value then theres repeated digit
if (splitString.contains(c))
{
return true;
}
splitString.add(c);
}
return false;
}
The problem is in this function:
public static boolean areThereRepeats(String value){
ArrayList<Character> splitString = new ArrayList<Character>();
for (char c : value.toCharArray()){
//if it already contains value then theres repeated digit
if (splitString.contains(c)){
return true;//Note that returning here only checks the first value that matches
}
splitString.add(c);
}
return false;
}
When you check to see if splitString.contains(c) it will return true if the array is length one. You aren't doing anything to check that the char c you're checking isn't comparing against itself.
Also note that Maraca has a point: the data structure you're choosing to utilize to record your remainders is flawed. areThereRepeats will work fine for checking if you assume that each new character represents a new remainder (or more specifically, the index into the base you're checking of the remainder you found). But why marshal all of that into a string in the first place? Why not pass the ArrayList to areThereRepeats?
public static boolean converties(int number, int base){
int remainder;
ArrayList<Integer>remainders = new ArrayList<Integer>();
while (number != 0){
remainder = number%base;
remainders.add(remainder);//Saves the index of the remainder in the current base, using an integer base-10 representation
number = number/base;
}
return areThereRepeats(remainders);
}
//Recursion ain't efficient, but...
public static boolean areThereRepeats(ArrayList<Integer> remainders){
if (remainders.size() <= 1) {
return false;
}
rSublist = remainders.sublist(1, remainders.size())
if (rSublist.contains(remainders.get(0)) {
return true;
}
return areThereRepeats(rSublist);
}
result+=Integer.toString(remainders.get(i));
In this line you add the remainder in base 10, so it will only work correctly if you find a match with base <= 10. Btw. It could be done very easily with BigInteger (if you don't want to do it yourself).
Otherwise:
result += (char)(remainders.get(i) < 10 ? ('0' + remainders.get(i)) : ('A' + remainders.get(i) - 10));
This will work up to base 36.
Or just use result += (char)remainders.get(i); it will work up to base 256, but it won't be readable.
And I agree with Nathaniel Ford, it would be better to pass the ArrayLists. If you still want to get the String in the standard way you can make another function to which you pass the ArrayList and transform it with the 1st method shown here.