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));
Related
I am trying to sort the digits of an Integer in descending order in JAVA but I am not allowed to use any array.
This was given to me as an assignment in class and below is a code that I tried but failed.
import java.util.Scanner;
class descend
{
public static void main(String args[])
{
int a=0,loc=0,parse=0,temp=0,big=0;
Scanner scan = new Scanner(System.in);
System.out.print("Enter a number");
a=scan.nextInt();
String s=Integer.toString(a);
int l=s.length();
for(int i=0;i<l;i++)
{
big=(int)(s.charAt(i));
loc=i;
for(int j=i+1;j<l;j++)
{
parse=(int)(s.charAt(j));
if(parse>big)
{
big = parse;
loc=j;
}
}
temp=parse;
s.charAt(i)=s.charAt(loc);
s.charAt(loc)=temp
}
System.out.print(s);
}
}
Here I get a syntax error at s.charAt(i)=s.charAt(loc); and s.charAt(loc)=temp; that a variable is required but a value is given.
Please help me out with this and I shall always be grateful to you.
Maybe the teacher want to test your knowledge about the new stream API. Or maybe he wants you to test your knowledge about Collections.sort() and LinkedList (which does not contain an internal array).
1.) Here is a solution with stream API:
int number = 52214;
String.valueOf(number).chars()
.sorted()
.map(Character::getNumericValue).forEach(System.out::print);
This will print out:
12245
2.) Here is a solution with collections:
List<Integer> list = new LinkedList<Integer>();
StringCharacterIterator iterator = new StringCharacterIterator(String.valueOf(number));
for (char c = iterator.first(); c != CharacterIterator.DONE; c = iterator.next())
{
list.add(Character.getNumericValue(c));
}
Collections.sort(list);
System.out.println("list=" + list);
This will print out:
list=[1, 2, 2, 4, 5]
String cannot be changed, only replaced, hence a = b; f(b); will never change a.
With 10 digits only, you could iterate, step through, from 0 upto 9 to have the sorting:
int number = ... // or String number
if (number == 0) { // or < 10
System.out.println(number);
} else {
for (int digit = 0; digit <= 9; ++digit) {
// While being able to remove the current digit:
for (;;) {
int scrapedNumber = numberWithoutDigitOnce(number, digit);
if (scrapedNumber == number) {
break;
}
number = scrapedNumber;
System.out.print(digit);
}
}
System.out.println();
}
int numberWithoutDigitOnce(int number, int digit) {
if (number % 10 == digit) {
return number / 10;
}
int n = numberWithoutDigitOnce(number/10, digit)*10 + (number % 10);
}
Zero is a special case.
A recursive solution, you find the highest digit in the String, add it to your output String, and remove it from your input String.
Repeat until your input String is empty.
Removing the character at a given index in a String can be achieve by concatenating the characters before the index and the ones after the index. (Or with a StringBuilder but I agree with the comments on the OP that it would be cheating to use a StringBuilder)
private static String sort(String digitsLeftToSort, String sortedString) {
if(digitsLeftToSort.length() == 0) { // no more character to sort
return sortedString;
} else {
// find the index of the highest digit
int index = findIndexOfHighestDigit(digitsLeftToSort);
// add the character at that index to your output String
sortedString += digitsLeftToSort.charAt(index);
// Remove it from your input String
digitsLeftToSort = digitsLeftToSort.substring(0, index) + digitsLeftToSort.substring(index+1);
// Recursive call with your new Strings
return sort(digitsLeftToSort, sortedString);
}
}
// This finds the index of the highest digit in the given String
private static int findIndexOfHighestDigit(String s) {
int highestDigitValue = -1;
int highestDigitIndex = -1;
int integerValue;
for(int i = 0; i< s.length(); i++) {
integerValue = Character.getNumericValue(s.charAt(i));
if(integerValue > highestDigitValue) {
highestDigitValue = integerValue;
highestDigitIndex = i;
}
}
return highestDigitIndex;
}
Then
String sortedString = sort("462375623478142", "");
System.out.println(sortedString);
Outputs
877665444332221
Sorry, But after applying so much effort, I figured it out.
int n=54321;char ch;
String s=Integer.toString(n);
int l= s.length();
for(int i=48;i<=57;i++) //ascii values from 0 - 9
{
for(int j=0;j<l;j++)
{
ch=s.charAt(j);
if(ch==(char)i) // checking if a digit equals a number
{
System.out.print(ch);
}
}
}
It sorts the digits in ascending order. To sort in descending order we should use
for(int i=57;i>=48;i--)
I tried coding a complete decimal to binary converter, which worked just fine and now I want to remove the unnecessary 0s from my output String, but it doesnt remove all of the 0s and I have no idea why.
Here is my code :
public class Converter {
private static final int[] ARRAY = {16348,8192,4096,2048,1024,512,256,128,64,32,16,8,4,2,1};
public static String toBinary(int number) {
String output = new String();
int number2 = number;
for (int i=0; i<ARRAY.length ; i++) {
if (number2 - ARRAY[i] >= 0) {
output += "1";
number2 -= ARRAY[i];
}
else {
output += "0";
}
}
boolean sorted = false;
int i = 0 ;
while (sorted == false) {
if (output.charAt(i) == '0') {
StringBuilder temp = new StringBuilder(output);
temp.deleteCharAt(i);
output = temp.toString();
i ++;
}
else{
sorted = true;
}
}
return output;
}
}
It's because the variable i is pointing to a wrong location. It's because after you remove the 0 at the ith you are incrementing i.
For example, take the string 00001 (a minified one in terms of number of bits)
When i = 0, after removing the 0 at index i we get 0001. On incrementing i becomes 1.
When i = 1, after removing the 0 at index i we get 001. On incrementing i becomes 2.
(We have already skipped past the first 0).
Removing i++ will do the trick. Still, your code does not work for input 0. In your while loop, you still need to validate the index i and break the while loop by checking if output string is empty.
A simple solution would be to use Integer.valueOf as suggested in this answer.
Or another one-liner would be:
String result = output.contains("1") ? output.substring(output.indexOf("1")) : "0";
I suggest to use simpler solution to remove trailing zero's by parsing the output to Integer
use this
int x = Integer.valueOf(output);
// if you wanted the output as string
String val = String.valueOf(x);
It is preferable that you don't add the leading zeroes in the first place. Why create, then remove? This method will not add leading zeroes until a one has been detected:
public static String toBinary(int number) {
String output = new String();
int number2 = number;
boolean foundOne = false;
for (int i=0; i<ARRAY.length ; i++) {
if (number2 - ARRAY[i] >= 0) {
output += "1";
number2 -= ARRAY[i];
foundOne = true;
}
else if (foundOne){
output += "0";
}
}
if (!foundOne)
output = "0";
return output;
}
String s = "00010101"
System.out.println(s.replaceAll("^0*", ""))
// => 10101
This is a example using regex.
^ means the expression should only match at the beginning of a string.
0*matches any string of characters that repeats 0 zero or more times
I was working on a question that requires a concatenation of strings recursively and ran into a problem.
Question states that s(0) = 0, s(1) = 1, s(n) = s(n-1)s(n-2) for n >= 2, where s(n) is the concatenated string of the previous two strings.
Input will indicate how many instances of (n, k) pair will be input as the first integer, followed by each line containing a non-negative integer
n (0 <= n <= 60) and a positive integer k.
Output is supposed to be printing out the kth character of the concatenated string s(n), where k is less or equal to the number of characters in string s(n).
s(0) = 0
s(1) = 1
s(2) = 10
s(3) = 101
s(4) = 10110
s(5) = 10110101
and so on.
Sample input:
3
5 2
0 1
4 3
Output:
0
0
1
My code:
import java.util.*;
public class recursivestring {
public static String recursive(int n, int i, String str1, String str2){
if (i == n - 1)
return str1 + str2;
return recursive(n, i + 1 , str1 + str2, str1);
}
public static void main(String[] args) {
int lines, i, n, k;
String result;
Scanner input = new Scanner(System.in);
lines = input.nextInt();
for (i = 0; i < lines; i++) {
n = input.nextInt();
k = input.nextInt();
if (n == 0) {
result = "0";
} else if (n == 1) {
result = "1";
} else if (n == 2) {
result = "10";
} else {
result = recursive(n, 2, "10", "1");
}
System.out.println(result.charAt(k-1));
}
}
}
This is what I have so far, and it works for the given sample test case. It works for most cases but once n becomes large, I get this error
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
Why is that happening and is there something wrong with my code?
Thank you!
The problem with your approach is that it creates too many throw-away strings. Each time you write
return str1 + str2;
a new String object is created. The number of such throw-away objects grows linearly with n, while their total length grows as O(n2).
You have two solutions to this problem:
Keep your program linear, and pass StringBuilder at the top level. Each recursive invocation would call append, rather than using operator + for concatenation.
Use Memoization - since the number of strings that you need to compute is small, storing the ones that you computed so far and re-using them should fix the problem.
A bigger issue with your problem limits is that its output cannot fit in a String: Java allows strings of up to 231 in length, while the output of your code for 60 is quite a bit longer - namely, 1,548,008,755,920 characters. While you should be able to save this output in a file, there is no way to store it as a String, with or without memoization.
Since you're doing this in Java and not in an FP language with tail call optimization, two things are wrong: recursion and string concatenation. In Java you would to iteration and string building with a mutable builder.
Specifically, your recursive function retains all the interim string you produce on your way to the full string. That's O(n2) memory usage.
Well, to be honest this looks like fibonacci to me so me approach looks a little like that...
public static void main(String[] args) {
for (int i = 0; i < 6; i++) {
System.out.println(stringbonacci(i));
}
}
private static String stringbonacci(int i) {
if (i == 0) {
return "0";
}
if (i == 1) {
return "1";
} else {
return stringbonacci(i - 1) + stringbonacci(i - 2);
}
}
and the result looks like:
0
1
10
101
10110
10110101
I highly recommend caching the result of each method call so that you don't have to re-calculate everything more than once. Will greatly improve your performance at the cost of a small bit of heap. Something like... this?
public class RecursiveString {
private static final Map<Integer, String> cache = new HashMap<>();
static {
cache.put(0, "0");
cache.put(1, "1");
}
public static String generateString(Integer i) {
if (i < 0) return generateString(0); // or something... avoid negatives.
if (cache.get(i) != null) return cache.get(i); // cache hit.
String generated = String.format("%s%s",
generateString(i-1), generateString(i-2));
cache.put(i, generated);
return generated;
}
}
Note that on a 2G heap, generateString works up through i=40 on my machine, simply due to the length of the resulting string. The string's length is going to be 2*fib(i) bytes in size, so your memory requirement is going to explode pretty quickly once you start hitting those indexes.
Same idea as the answer with the map (store the intermediate string, don't recompute), but using an array instead.
This could be optimized a little more by reading all the lines, then finding the maximum n value, thereby storing only one array, then looping back over the (n, k) pairs.
import java.util.Scanner;
public class BinaryConcat {
private String[] dict;
public BinaryConcat(int n) {
if (n < 0) throw new IllegalArgumentException();
dict = new String[2 + n]; // Have 2 base cases
dict[0] = "0";
dict[1] = "1";
}
public String getValue(int n) {
if (n < 0) throw new IllegalArgumentException();
if (n <= 1) return dict[n];
if (dict[n] == null || dict[n].isEmpty()) {
dict[n] = String.format("%s%s", getValue(n - 1), getValue(n - 2));
}
return dict[n];
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int lines = input.nextInt();
input.nextLine(); // consume linefeed
for (int i = 0; i < lines; i++) {
String line = input.nextLine();
String[] nk = line.split(" ");
int n = Integer.parseInt(nk[0]);
int k = Integer.parseInt(nk[1]);
String value = new BinaryConcat(n).getValue(n);
System.out.println(value.charAt(k - 1));
}
}
}
Sample run
(same input and output as expected)
i want to know if i can get the last digit of the input, but if the last one is 0 i want it to ignore it and take the one before it... like bob120, last digit is 20 not 0, to make it the level for the person
here is my code and i tried for 2 days to know how but i'm stuck with this problem.
and i tried %10 but still it's the same problem.
number = number.substring(5,6);
level = Integer.parseInt(number);
I'm using scanner package
thank you in advance
if the input is a String and you like the use substring the code will be
int pos= number.lenght();
String lastChar = number.substring(pos-1,pos);
Note: number is a String : )...
Then you are right on the Integer.parseInt(), be aware of error if its not a number (try, catch)...
Then you need a if statement...change your pos and try again....
To do this task it would be better to use the String.toCharArray() at loop it backwards... so if you have time study this..
Something like this:
public int getLastNumDifThenZero(String text){
char[] ca = text.toCharArray();
for (int i = ca.length-1; i >= 0; i--) {
char a = ca[i];
try {
int n = Integer.parseInt(String.valueOf(a));
if (n!=0){
return n;
}
} catch (NumberFormatException e) {
//Not a number
}
}
return -1;
}
You can loop from the end of String and search for 'non-zero' value (result char is String) :
public static void main(String[] args) {
// example returns 7
String num = "85677000";
char lastDigit =' ';
// looping from end and searching non zero digit
for(int i=num.length()-1 ; i>=0 ;i--){
lastDigit=num.charAt(i);
if (lastDigit != '0'){
System.out.println(lastDigit);
break;
}
}
}
I know I'm missing some things and that's what I really need help with. The code doesn't work in all cases and am looking for help improving/fixing it.
Assignment:
The code I have so far:
public String word(int num, String words)
{
int l = words.indexOf(" ");
int r = words.indexOf(" ", l+1);
for(int i = 3; i <= num; i++){
l = r;
r = words.indexOf(" ", l+1);
//if(i != num)
// l = r;
}
String theword = words.substring(l,r);
return theword;
}
}
As this is clearly homework, I will give you text only.
Your approach may work eventually, but it is laborious and overly complicated, so it's hard to debug and hard to get right.
make use of String's API by using the split() method
after splitting the sentence into an array of word Strings, return the element at num less one (array are indexed starting at zero
check the length of the array first, in case there are less words than num, and take whatever action you think is appropriate in that case
For part 2, a solution in a simple form may be:
create a new blank string for the result
iterate over the characters of the given string adding the character to the front of the result string
make use of String's toUpperCase() method
Since this is homework and you have showed some effort. This is how you can do part 1 of your question. This code is pretty evident.
1) I am returning null if number is greater than the number of words in string as we dont want user to enter 5 when there are only 2 words in a string
2) Splitting the string by space and basically returning the array with the number mentioned by user
There are more conditions which you must figure out such as telling the user to enter a number of the string length since it would not give him any result and taking input from Scanner instead of directy adding input in method.
public static String word(int num, String words)
{
String wordsArr[] = words.split(" ");
if(num <= 0 || num > wordsArr.length) return null;
return (wordsArr[num-1]);
}
the second part of your question must be attempted by you.
Well... not often you see people coming here with homework AND showing effort at the same time so bravo :).
This is example of how you can split the string and return the [x] element from that string
public class SO {
public static void main(String[] args) throws Exception {
int number = 3;
String word = "Hello this is sample code";
SO words = new SO();
words.returnWord(number, word);
}
private void returnWord(int number, String word) throws Exception {
String[] words = word.split("\\s+");
int numberOfWords = words.length;
if(numberOfWords >= number) {
System.out.println(words[number-1]);
} else {
throw new Exception("Not enought words!!!");
}
}
}
Yes it is a working example but do not just copy and paste that for your homework - as simple question from teacher - What is this doing, or how this works and your out :)! So understand the code, and try to modify it in a way that you are familiar what is doing what. Also its worth getting some Java book - and i recommend Head first Java by O'Really <- v.good beginner book!
if you have any questions please do ask!. Note that this answer is not 100% with what the textbook is asking for, so you can modify this code accordingly.
As of part 2. Well what Bohemian said will also do, but there is a lot quicker solution to this.
Look at StringBuilder(); there is a method on it that will be of your interest.
To convert String so all letter are upper case you can use .toUpperCase() method on this reversed string :)
You can try:
public class trial {
public static void main(String[] args)
{
System.out.println(specificword(0, "yours faithfully kyobe"));
System.out.println(reverseString("derrick"));}
public static String specificword(int number, String word){
//split by space
String [] parts = word.split("\\ ");
if(number <= parts.length){
return parts[number];
}
else{
return "null String";
}
}
public static String reverseString(String n){
String c ="";
for(int i = n.length()-1; i>=0; i--){
char m = n.charAt(i);
c = c + m;
}
String m = c.toUpperCase();
return m;
}
}
For the first problem, I'll give you two approaches (1. is recommended):
Use the String.split method to split the words up into an array of words, where each element is a word. Instead of one string containing all of the words, such as "hello my name is Michael", it will create an array of the words, like so [hello, my, name, is, Michael] and that way you can use the array to access the words. Very easy:
public static String word(int num, String words)
{
// split words string into array by the spaces
String[] wordArray = words.split(" "); // or = words.split("\\s+");
// if the number is within the range
if (num > 0 && num <= wordArray.length) {
return wordArray[num - 1]; // return the word from the word array
} else { // the number is not within the range of words
return null;
}
}
Only use this if you cannot use arrays! Loop through the word until you have found enough spaces to match the word you want to find:
public static String word(int num, String words)
{
for (int i = 0; i < words.length(); i++) { // every character in words
if (words.substring(i, i+1).equals(" ")) { // if word is a space
num = num - 1; // you've found the next word, so subtract 1 (number of words left is remaining)
}
if (num == 1) { // found all words
// return this word
int lastIndex = i+1;
while (lastIndex < words.length()) { // until end of words string
if (words.substring(lastIndex, lastIndex+1).equals(" ")) {
break;
}
lastIndex = lastIndex + 1; // not a space so keep moving along the word
}
/*
// or you could use this to find the last index:
int lastIndex = words.indexOf(" ", i + 1); // next space after i+1
if (lastIndex == -1) { // couldn't find another space
lastIndex = words.length(); // so just make it the last letter in words
}*/
if (words.substring(i, i+1).equals(" ")) { // not the first word
return words.substring(i+1, lastIndex);
} else {
return words.substring(i, lastIndex);
}
}
}
return null; // didn't find word
}
As for the second problem, just iterate backwards through the string and add each letter to a new string. You add each letter from the original string to a new string, but just back to front. And you can use String.toUpperCase() to convert the string to upper case. Something like this:
public static String reverse(String str) {
String reversedString = ""; // this will be the reversed string
// for every character started at the END of the string
for (int i = str.length() - 1; i > -1; i--) {
// add it to the reverse string
reversedString += str.substring(i, i+1);
}
return reversedString.toUpperCase(); // return it in upper case
}