Run-length encoding in java [closed] - java

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
How to print out the number of a specific digit along with the digit itself in form "nxw." n is the frequency of the number, w is the number itself.
So, for example, if the user's input was 1 1 1. The output would be 3x1.
If the user's input was 1 1 1 at the first line and 7 7 1 1 0 at the second line. The output would be 3x1.2x7.2x1.1x0. with no spaces.
Note:
loop ends with a dot.
numbers don't have to be in a specific order
user can input as many digits as they want.
So for example, Input can be 1 1 1 at the first line 7 7 1 1 0 at the second ... etc.
This is my code so far. But I know that it's not true.
import java.util.*;
public class LaufLaengenKodierung {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int freq = 0;
int oldNum = 0;
int num = 0;
boolean first = true;
while(sc.hasNextInt()) {
int i = sc.nextInt();
if(i == oldNum) {
freq++;
num = i;
} else if(i != oldNum) {
freq = 1;
oldNum = i;
num = i;
if(first) {
first = false;
num = i;
freq = 1;
}
}
}
System.out.print(freq + "x" + num + ".");
sc.close();
}
}

Existing code needs to be slightly refactored to print the frequency and integer value as soon as a sub-sequence of the same values ends.
static void printRLE(String input) {
Scanner sc = new Scanner(input);
int freq = 0;
int oldNum = 0;
boolean first = true;
while(sc.hasNextInt()) {
int i = sc.nextInt();
if (i != oldNum || first) {
if (first)
first = false;
else // integer value changed
System.out.printf("%dx%d.", freq, oldNum);
oldNum = i;
freq = 1;
} else {
freq++;
}
}
if (!first)
System.out.printf("%dx%d.%n", freq, oldNum);
else
System.out.println("No integer found"); // or print 0x0 if it's correct
sc.close();
}
Tests:
String[] tests = {
"",
"abc.",
"11 11 11",
"1 1 1\n7 7 1 1 0",
"0 0 0",
};
for (String test: tests) {
System.out.println("test=[" + test + "]");
printRLE(test);
System.out.println("--------");
}
Output:
test=[]
No integer found
--------
test=[abc.]
No integer found
--------
test=[11 11 11]
3x11.
--------
test=[1 1 1
7 7 1 1 0]
3x1.2x7.2x1.1x0.
--------
test=[0 0 0]
3x0.
--------
Update
If separate digits need to be counted only (not the integer numbers), e.g. input 11 11 11 should be converted to 6x1. instead of 3x11. as shown above, the method should be refactored to process the digits inside numbers:
static void printRLEDigits(String input) {
Scanner sc = new Scanner(input);
int freq = 0;
int oldNum = 0;
boolean first = true;
out: while(sc.hasNext()) {
String s = sc.next(); // getting "number" delimited with whitespaces
for (char c: s.toCharArray()) {
if (!Character.isDigit(c)) {
break out;
}
int i = c - '0';
if (i != oldNum || first) {
if (first)
first = false;
else // digit changed
System.out.printf("%dx%d.", freq, oldNum);
oldNum = i;
freq = 1;
} else {
freq++;
}
}
}
if (!first)
System.out.printf("%dx%d.%n", freq, oldNum);
else
System.out.println("No integer found");
sc.close();
}
Output for tests: "11 11 11", "112 223", "1 1 1\n7 7 1 1 0", "0 0 0":
test=[11 11 11]
6x1.
--------
test=[112 223]
2x1.3x2.1x3.
--------
test=[1 1 1
7 7 1 1 0]
3x1.2x7.2x1.1x0.
--------
test=[0 0 0]
3x0.
--------
Online demo of both methods printRLE and printRLEDigits

You have to save the count of each individual digit. You can do this by creating an int array of size 10, for the digits 0 to 9. Then it's a simple loop like
while(sc.hasNextInt()) {
int i = sc.nextInt();
countArray[i]++;
}
After that you check each element in the array and output the count of the digit, when it is bigger than 0. It can look like this:
for (int i=0; i<countArray.length; i++) {
if (countArray[i] > 0) {
System.out.printf("%dx%d.", countArray[i], i);
}
}
Keep in mind that you have to check if the number entered by the user is in the limit of 0 to 9, otherwise you run into ArrayIndexOutOfBoundsExceptions.

Related

binary to decimal converter without using parseint or arrays

Getting string index out of range but I don't understand why I've went through it about 50 times
import java.util.Scanner;
public class binary {
public static void main(String[] args) {
System.out.println("Enter the first binary number");
Scanner keyboard = new Scanner(System.in);
String num1 = keyboard.next();
//System.out.println("Enter the second binary number");
//String num2 = keyboard.next();
int total = 0;
for(int i = num1.length(); i>0;i--) {
if(num1.charAt(i) == 1) {
total += 2*i;
}
}
if(num1.charAt(3) == 1) {
total -= 1;
}
System.out.println(total);
}
}
Here's a complete solution to what you're trying to do, including a set of tests:
class binary {
private static int binaryToInt(String binary) {
int total = 0;
for (int i = 0 ; i < binary.length(); i++) {
total *= 2;
if (binary.charAt(i) == '1')
total += 1;
}
return total;
}
private static void test(String binary, int expected) {
int n = binaryToInt(binary);
String rightWrong = "right";
if (n != expected) {
rightWrong = String.format("WRONG! (should be %d)", expected);
System.out.printf("%s -> %d is %s\n", binary, n, rightWrong);
}
public static void main(String[] args) {
test("0", 0);
test("1", 1);
test("10", 2);
test("100", 4);
test("111", 7);
test("0000111", 7);
test("1010101010", 682);
test("1111111111", 1023);
System.out.println("");
// test sanity check
System.out.println("This last test should fail (we are just testing the test method itself here)...");
test("1010101010", 0);
}
}
Result:
0 -> 0 is right
1 -> 1 is right
10 -> 2 is right
100 -> 4 is right
111 -> 7 is right
0000111 -> 7 is right
1010101010 -> 682 is right
1111111111 -> 1023 is right
This last test should fail (we are just testing the test method itself here)...
1010101010 -> 682 is WRONG! (should be 0)
One significant problem in your code hasn't yet been addressed in the comments or earlier answers. Note this line vs the one in your code:
if (binary.charAt(i) == '1')
You were testing for the numeric value 1, which is never going to be true because you're getting back a character from charAt(), not a number.
While length() counts the number of elements, their indexes start at 0. For a string of "1111" the last character would be at index 3, not 4, so .length()-1. You would need to either change your for statement to for(int i = num1.length()-1; i>=0;i--) (notice also the condition change) or change the charAt statement to if(num1.charAt(i-1) == '1').
Also, based on what you are trying to do, I assume for total += 2*i you actually need something like total += Math.pow(2, i-length()) depending on what you decide to do with i first.

Print odd numbers in a descending order

The program needs to take an odd number and output it in a descending order
For example: if the input is 11 the output needs to be 11 , 9 , 7 , 5 , 3, 1.
I tried using a for loop but I can only seem to get it to work with even numbers not odd numbers
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int number = input.nextInt();
for (int i = number - 1; i >= 0; i--) {
if (i % 2 == 0) {
int descend = i;
System.out.println(descend + " ");
}
}
}
The output is the number in descending order but as even only. If I add a 1 into the descend variable the numbers would seem to descend in an odd manner but its not ideal.
This line returns true if the number is even:
if (i % 2 == 0) {
If you want to know when the number is odd:
if (i % 2 != 0) {
Also, why are you starting your count at 1 less than the input value:
int i = number - 1;
I think you want to do this:
for (int i = number; i > 0; i--) { // tests for numbers starting at the input and stopping when i == 0
Just replace (i%2==0) to (i%2==1)
Asking if the number % 2 is equal to zero is basically asking if the number is even, so what you really have to do is ask if the number % 2 is not equal to zero, or equal to 1
if (i % 2 != 0) {
int descend = i;
System.out.println(descend + " ");
}
Also, there's no need to subtract 1 from the user input so your for loop can be written like this
for (int i = number; i >= 0; i--) {
if (i % 2 == 0) {
int descend = i;
System.out.println(descend + " ");
}
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Enter an an odd number: ");
int number = input.nextInt();
while(number%2==0){
System.out.print("Number must be odd number:" +
"(Ex:1, 3,5)\nTry again: ");
number=input.nextInt();
}
for (int i = number; i >= 0; i--) {
if(number%2!=0){
System.out.println(number);}
number-=1;
}
}

Strange loop behavior in java [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I'm a java learner and I have a task to do from a forum to learn more.
The challenge is receive a number and multiply it by it's own digit like:
input 999
output `9*9*9 = 729 then 7*2*9 =126 again 1*2*6 = 12 finally 1*2=2 until it hits only one single digit.
I got this issue which I ask a variable to add the multiplication of an array of length of 2 it returns me this
1------------------1
49-----------------2
final result 2450
And this is the code..
class Persist {
public static void persistence(long n) {
String number = String.valueOf((int)n);
char[] digits1 = number.toCharArray();
int value = 1;
for(int i = 0 ;i <= digits1.length -1;i++) {
System.out.println(value + "-----------------" + digits1[i]);
value = value* (int)digits1[i];
}
System.out.println((int)value);
}
public static void main(String [] args) {
persistence(12);
}
}
I can try to fix this but I'm interested to know whats wrong.Thank you all in advanced for the help and just by passing by.
You are using the ASCII values of the numbers (see https://en.wikipedia.org/wiki/ASCII) i.e. 1=49 and 2=50
49 * 50 = 2450
You can use the Character.getNumericValue to get the numerical value of the char instead, i.e.
class Persist {
public static void persistence(long n) {
String number = String.valueOf((int)n);
char[] digits1 = number.toCharArray();
int value = 1;
for(int i = 0 ;i <= digits1.length -1;i++) {
System.out.println(value + "-----------------" + digits1[i]);
value = value* Character.getNumericValue((int)digits1[i]);
}
System.out.println((int)value);
}
public static void main(String [] args) {
persistence(12);
}
It is easiest to understand if you look at the values with a debugger. During the actual calculation value = value * (int)digits1[i] you are not using the value of the digits but the ASCII value of the chars. This is 1->49 and 2->50 so you are calculating 49*50=2450.
Change the line to value = value* Character.getNumericValue(digits1[i]); and you get what you are looking for.
Here's how I would do this. I adjusted it so that a 0 value digit is converted to 1. You can comment that out (did this because any digit of 0 turns the answer into 0). This version will keep re-multiplying until it's down to one digit.
public class Persist {
public static void main(String [] args) {
int answer = persistence(234);
System.out.println(" length: " + String.valueOf(answer).length());
while ( String.valueOf(answer).length() > 1) {
answer = persistence(answer);
} }
static int persistence(int n) {
int value = 1;
String myStr = String.valueOf(n);
int myStrLen = myStr.length();
int[] finalIntAr = new int[myStrLen];
for (int v=0; v< myStrLen; v++) {
String subS= myStr.substring(v,v+1);
System.out.println("the char/int : " + subS);
Integer bigI = Integer.valueOf(subS);
if (bigI == 0) { bigI = 1; } // take this out if you want 0 to perform as 0
finalIntAr[v] = bigI.intValue();
}
for (int i = 0 ; i < myStrLen; i++) {
System.out.println(" ----- first= " + value + " multiplied by : " + finalIntAr[i]);
value = value * finalIntAr[i];
}
System.out.println("\n CURRENT FINAL VALUE *** : " + value);
return value;
} }
Output:
the char/int : 2
the char/int : 3
the char/int : 4
----- first= 1 multiplied by : 2
----- first= 2 multiplied by : 3
----- first= 6 multiplied by : 4
CURRENT FINAL VALUE *** : 24
length: 2
the char/int : 2
the char/int : 4
----- first= 1 multiplied by : 2
----- first= 2 multiplied by : 4
CURRENT FINAL VALUE *** : 8
Since nobody posted an answer using no strings or chars, I will. Technically not an answer to your question, though.
public static void persistence(long x)
{
long answer = 1;
while (x != 0) {
long onesDigit = x % 10;
answer *= onesDigit;
x /= 10;
}
System.out.println(answer);
}

Project Euler #18: Maximum Path Sum I

So basically I interpreted this problem as follows:
3
7 4
2 4 6
8 5 9 3
The two number below the starting should be compared and the larger should be picked as the new number. So in this case, it would be 3, then 7, then 4, then 9. Sum them up, get the answer of 23. I wrote a program to achieve this:
public class ProblemEighteen {
private static int pos = 1;
public static void main(String[] args) {
try {
Scanner in = new Scanner(new File("Problem18Text"));
int sum = 0;
while (in.hasNextLine()) {
final String line = in.nextLine();
int big = getBiggestNum(line);
sum += big;
System.out.println(big);
}
System.out.println(sum);
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private static int getBiggestNum(String line) {
final String[] numbers = line.split(" ");
if (numbers.length == 1) {
pos = 1;
return Integer.parseInt(numbers[0]);
} else {
int i = 1;
int numOne = -1;
int numTwo = -1;
for (final String num : numbers) {
if (pos == i) {
numOne = Integer.parseInt(num);
} else if (pos + 1 == i) {
numTwo = Integer.parseInt(num);
}
i++;
if (numOne != -1 && numTwo != -1)
break;
}
if (numOne > numTwo) {
return numOne;
} else {
pos += 1;
return numTwo;
}
}
}
It works fine for the example I gave above, but when I put in the actual problem to solve, it said I got it wrong (I got 1064). I added a print statement to see what numbers it was selecting and it got them all right (based on how I understood what I was trying to find) but I still got it wrong... Anyone know why?
It's been a while since I've solved this problem, but you'll find that it's best that you start at the bottom of the triangle and work your way up. Especially, when you get to problem 67.
If you read your data into an array as baum suggested, you'd have data that looks like this:
3 0 0 0
7 4 0 0
2 4 6 0
8 5 9 3
So start at the bottom taking two numbers at a time and comparing a sum to their adjacent number in the next above row.
8 + 2 = 10 or 5 + 2 = 7. 10 is greater so replace the 2 with the 10.
5 + 4 = 9 or 9 + 4 = 13. 13 is greater so replace the 4 with the 13.
9 + 6 = 15 or 3 + 6 = 9. 15 is greater so replace the 6 with 15.
Now move up one row and perform the same checks until you get to the very top and the very top should contain the correct answer.

i want to print all armstrong number between 1 to 1000 in a textbox using awt or swing but i only get last value by my code .So plc help me

i want to print all armstrong number between 1 to 1000 in a textfield using awt or swing but i only get last value by my code .So pls help me
public void actionPerformed(ActionEvent e)
{
String s1=tf.getText();
int n1=Integer.parseInt(s1);
for(int n=0;n<10000;n++)
{
int sum=0;
int number=n;
int original=number;
while(number>0)
{
int r=number%10;
sum+=r*r*r;
number=number/10;
}
if(sum==original)
{
tf1.setText(String.valueOf(original[i]));
}
}
}
For those who don't know, an Armstrong number (or narcissistic number) is a number with n digits that is equal to the sum of each of its digits to the nth power.
(x1*10(n-1))+(x1*10(n-2))...+(x1*10(n-n)) = (x1)n+(x2)n...+(xn)n
This means that if the number is 1 digit, the power will be 1.
Therefore there are 10 1 digit numbers that are Armstrong numbers:
0 = 01
1 = 11
2 = 21
3 = 31
4 = 41
5 = 51
6 = 61
7 = 71
8 = 81
9 = 91
Your code, as written, will not identify any of those numbers as Armstrong numbers.
Your code will also incorrectly identify some numbers as 4 digit Armstrong numbers because you only look for the the cubes (3rd power) of your numbers not the 4th power.
(You don't have to worry about twos because there are no two digit Armstrong numbers)
In order to correctly determine all the possible Armstrong numbers between 1 and 10000, you need to write a "power" loop that finds the nth power of a number by multiplying the number n times.
This would look something like:
//... beginning of your original function
//added a string to hold all the values before printing
string holder = "";
for(int n=0;n<10000;n++){
int sum=0;
//n=original you had duplicate variables (just use n as original)
int number = n;
//while there are still digits left
while(number>0){
//get the smallest digit
int r=number%10;
//----------"Power" loop-----------
int foo = n;
//once smaller than 10, it's only a power of 1 (which is itself)
while(foo>=10){
//this means foo = foo/10
foo /= 10;
//this means r = r*r
r*=r;
}
//this means sum = sum+r
sum += r;
//you should have the hang of it by now
number/=10;
}
//if the sum equals the original number
if(sum==n){
//put that number into the end of a string (separated by newlines `\n`)
holder+=n+"\n";
}
}
//All done, so set the text box value
tf1.setText(holder);
//... whatever code you want to finish up
This should also take care of your problem with the textBox getting overwritten each time. By saving the numbers into a string and then printing all of them at once, only once (no overwriting), you'll get better results.
You always set the current found value. But you should set the previous found values + current found value.
tf1.setText(String.valueOf(original));
But more performant would be to use a stringbuilder object and append the result each time and set this value to the textfield outside the loop.
public void actionPerformed(ActionEvent e)
{
StringBuilder s = new StringBuilder ();
for(int n=0;n<10000;n++)
{
int sum=0;
int number=n;
int original=number;
while(number>0)
{
int r=number%10;
sum+=r*r*r;
number=number/10;
}
if(sum==original)
{
s.append(original + " ");
}
}
tf1.setText (stringBuilder.toString ());
}
Easy, all you do is change the setText() method of the TextField1 component with append().
It works! The remaining will do! Try it once.
public void actionPerformed(ActionEvent e)
{
String s1=tf.getText();
int n1=Integer.parseInt(s1);
for(int n=0;n<10000;n++)
{
int sum=0;
int number=n;
int original=number;
while(number>0)
{
int r=number%10;
sum+=r*r*r;
number=number/10;
}
if(sum==original)
{
tf1.append(String.valueOf(original[i] + " "));
}
}
}
Very simple program in C to list all armstrong number between 1 to 1000000.
#include<stdio.h>
#include<conio.h>
#include<math.h>
main()
{
long a = 1, c=0, b, e, f, d = 0,g=0,p,j,count=0;
printf("All armstron number between 1 and 1000000 is listed below!\n");
while (c <= 1000000)
{
j = c;
if (j >= 10)
{
while (j >= 10)
{
j = j / 10;
g++;
}
}
p = g + 1;
g = 0;
a = c;
f = a;
while (a >= 10)
{
b = a % 10;
d = d + pow(b,p);
a = a / 10;
}
e = pow(a,p) + d;
d = 0;
if (e == f)
{
count++;
printf("%ld\t",count );
printf("%ld\n", f);
}
c++;
}
getch();
}

Categories