How to remove last comma [duplicate] - java

This question already has answers here:
How to remove the last comma from the output in java? [duplicate]
(4 answers)
Closed 3 months ago.
public class Main {
public static void main(String[] args) {
// positive number
int number = 6;
System.out.print("Factors of " + number + " are: ");
// loop runs from 1 to 60
for (int i = 1; i <= number; ++i) {
// if number is divided by i
// i is the factor
if (number % i == 0) {
System.out.print(i + ",");
}
}
}
}
And my output is "1,2,3,6," but i want it like "1,2,3,6"
How can i do that?
No matter what i do it did not worked.

The simple and robust solution is to store the values in a list, and only then display them. This way you'll easily know when you're printing the last element. Besides, then you could just do something like:
List<String> divisors = new ArrayList<>();
// loop runs from 1 to 60
for (int i = 1; i <= number; ++i) {
// if number is divided by i
// i is the factor
if (number % i == 0) {
divisors.add(String.valueOf(i));
}
}
System.out.println(String.join(",", divisors));

Solution written by #abel1502 is the simplest if you want to display the values and keep them to use elsewhere. If you just want to display them, then there are more modern ways to do it (if you use a recent version of Java) :
var number = 60;
System.out.println(
IntStream.rangeClosed(1, number)
.filter(i -> number % i == 0)
.mapToObj(String::valueOf)
.collect(Collectors.joining(","))
);

There are multiple ways to solve it. In your case since the last 'i' in the loop is always number itself, and it should be on the list since (number%number==0), you can simply do something like this:
public class Main {
public static void main(String[] args) {
// positive number
int number = 6;
System.out.print("Factors of " + number + " are: ");
// loop runs from 1 to 60
for (int i = 1; i < number; ++i) { //< instead of <=, to exclude i==number
// if number is divided by i
// i is the factor
if (number % i == 0) {
System.out.print(i + ",");
}
}
//in your case
System.out.print(number);
}
}

Related

Optimized way to count number of occurrences of a digit in a range of numbers [duplicate]

This question already has answers here:
How to count each digit in a range of integers?
(11 answers)
Closed last year.
I've been trying to find the most optimized way to compute the number of occurrences of each digit from 0 to 9 in a random range of numbers typed in by the user for a random personal project.
Say, the user enters 1 as the lower bound (inclusive) and 20 as the upper bound (inclusive). Output should be like this:
2 12 3 2 2 2 2 2 2 2
User can only enter positive integers.
Now, the below code runs fine for small range of numbers/ small bounds, however, as expected it takes 4 seconds+ on my laptop for large numbers/range.
I've been trying to find a way to make things quicker, I used modulus to get the digits thinking maybe string conversion is to blame, but it didn't increase speed that much. I want to reduce runtime to less than 2 seconds. There must be a way, but what? Here is my original code:
import java.util.Scanner;
public class CountDigitsRandomRange {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
String g = s.nextLine();
while (!g.equals("0 0")) {
String[] n = g.split(" ");
long x = Long.parseLong(n[0]);
long y = Long.parseLong(n[1]);
long zero = 0;
long one = 0;
long two = 0;
long three = 0;
long four = 0;
long five = 0;
long six = 0;
long seven = 0;
long eight = 0;
long nine = 0;
for (long i = x; i <= y; i++) {
String temp = String.valueOf(i);
for (int j = 0; j < temp.length(); j++) {
if (temp.charAt(j) == '0') {
zero++;
}
if (temp.charAt(j) == '1') {
one++;
}
if (temp.charAt(j) == '2') {
two++;
}
if (temp.charAt(j) == '3') {
three++;
}
if (temp.charAt(j) == '4') {
four++;
}
if (temp.charAt(j) == '5') {
five++;
}
if (temp.charAt(j) == '6') {
six++;
}
if (temp.charAt(j) == '7') {
seven++;
}
if (temp.charAt(j) == '8') {
eight++;
}
if (temp.charAt(j) == '9') {
nine++;
}
}
}
System.out.println(zero + " " + one + " " + two + " "+three + " " + four
+ " " + five + " " + six + " " + seven + " " + eight + " " + nine);
g=s.nextLine();
}
}
}
I've seen some solutions online similar to my issue but they're mostly in C/C++, I don't get the syntax.
Here is a simple implementation that uses modulus. If you want a faster code, you will need to find some smart formula that gives you the result without performing the actual computation.
import java.util.Arrays;
public class Counter
{
private static long[] counts = new long[10];
public static void count(long x, long y)
{
Arrays.fill(counts, 0);
for(long val=x; val<=y; val++)
count(val);
}
public static void count(long val)
{
while(val>0)
{
int digit = (int)(val % 10);
counts[digit]++;
val /= 10;
}
}
public static void main(String[] args)
{
count(1, 20);
System.out.println(Arrays.toString(counts));
}
}
Output:
[2, 12, 3, 2, 2, 2, 2, 2, 2, 2]
So here is an issue you might not be aware of #Sammie. In my opinion, you should NOT use the seconds provided by your runner in Java to count time when it comes to making operations more efficient. As far as I am informed, a more objective calculation is to use internal methods of Java which depend on the CPU clock to count time. This way there is less variation between different PC's (although this I don't believe is fully eliminated). Please check my references below:
Clock milis (only use this if you cannot use the solution below)
Nanoseconds
Edit: Here is another stack overflow post discussing this matter. Nanoseconds seem to be preferable.
All you need to do after that is convert into minutes, and you should now be calculating more precisely.

Formatting returned Strings?

I'm really new to coding and just got assigned my first coding homework involving methods and returns. I managed to struggle through and end up with this, which I'm pretty proud of, but I'm not quite sure it's right. Along with that, my return statements are all on the same lines instead of formatted how my teacher says they should be ("n is a perfect number", then the line below says "factors: x y z", repeated for each perfect number. Below are the exact instructions plus what it outputs. Anything will help!
Write a method (also known as functions in C++) named isPerfect that takes in one parameter named number, and return a String containing the factors for the number that totals up to the number if the number is a perfect number. If the number is not a perfect number, have the method return a null string (do this with a simple: return null; statement).
Utilize this isPerfect method in a program that prompts the user for a maximum integer, so the program can display all perfect numbers from 2 to the maximum integer
286 is perfect.Factors: 1 2 3 1 2 4 7 14
It should be
6 is perfect
Factors: 1 2 3
28 is perfect
Factors: 1 2 4 7 14
public class NewClass {
public static void main(String[] args) {
Scanner input = new Scanner(System.in) ;
System.out.print("Enter max number: ") ;
int max = input.nextInt() ;
String result = isPerfect(max) ;
System.out.print(result) ;
}
public static String isPerfect(int number) {
String factors = "Factors: " ;
String perfect = " is perfect." ;
for (int test = 1; number >= test; test++) {
int sum = 0 ;
for (int counter = 1; counter <= test/2; counter++) {
if (test % counter == 0) {
sum += counter ;
}
}
if (sum == test) {
perfect = test + perfect ;
for (int counter = 1; counter <= test/2; counter++) {
if (test % counter == 0) {
factors += counter + " " ;
}
}
}
}
return perfect + factors ;
}
}
Couple of things you could do:
Firstly, you do not need two loops to do this. You can run one loop till number and keep checking if it's divisible by the iterating variable. If it is, then add it to a variable called sum.
Example:
.
factors = []; //this can be a new array or string, choice is yours
sum=0;
for(int i=1; i<number; i++){
if(number % i == 0){
sum += i;
add the value i to factors variable.
}
}
after this loop completes, check if sum == number, the if block to return the output with factors, and else block to return the output without factors or factors = null(like in the problem statement)
In your return answer add a newline character between perfect and the factors to make it look like the teacher's output.
You can try the solution below:
public String isPerfect(int number) {
StringBuilder factors = new StringBuilder("Factors: ");
StringBuilder perfect = new StringBuilder(" is perfect.");
int sum = 0;
for (int i = 1; i < number; i++) {
if (number % i == 0) {
sum += i;
factors.append(" " + i);
}
}
if (sum == number) {
return number + "" + perfect.append(" \n" + factors);
}
return number + " is not perfect";
}
Keep separate variables for your template bits for the output and the actual output that you are constructing. So I suggest that you don’t alter factors and perfect and instead declare one more variable:
String result = "";
Now when you’ve found a perfect number, add to the result like this:
result += test + perfect + '\n' + factors;
for (int counter = 1; counter <= test/2; counter++) {
if (test % counter == 0) {
result += counter + " ";
}
}
result += '\n';
I have also inserted some line breaks, '\n'. Then of course return the result from your method:
return result;
With these changes your method returns:
6 is perfect.
Factors: 1 2 3
28 is perfect.
Factors: 1 2 4 7 14
Other tips
While your program gives the correct output, your method doesn’t follow the specs in the assignment. It was supposed to check only one number for perfectness. Only your main program should iterate over numbers to find all perfect numbers up to the max.
You’ve got your condition turned in an unusual way here, which makes it hard for me to read:
for (int test = 1; number >= test; test++) {
Prefer
for (int test = 1; test <= number; test++) {
For building strings piecewise learn to use a StringBuffer or StringBuilder.
Link
Java StringBuilder class on Javapoint Tutorials, with examples.

How can I optimize This Code Into Lesser Line of Code

How can I optimize this code.
I want to reduce lines of code.
public class CoolDude {
public static void main(String[] args) {
for(int i = 100; i <= 500; ++i) {
if(i%5 == 0 && i%11 == 0) {
System.out.print("Cool Dude- ");
System.out.print(i + "\n");
} else if (i%5 == 0) {
System.out.print("Cool - ");
System.out.print(i + "\n");
} else if (i%11 == 0) {
System.out.print("Dude - ");
System.out.print(i + "\n");
}
}
}
}
Is there any way ?
While Stephen M Irving's answer is pretty spot on and corrects all the beliefs found in your question, this still answers your question, trying to minimize the number of statements.
public class CoolDude {
public static void main(String[] args) {
for (int i = 100; i <= 500; i++)
if (i % 5 == 0 || i % 11 == 0) // This is the condition where we decide to print something
System.out.printf("%s%s- %d%n", i % 5 == 0 ? "Cool " : "", i % 11 == 0 ? "Dude " : "", i);
}
}
However, this code duplicates one of the most expensive part: the modulo. Also, this solution is not readable !
When trying to figure solutions is useful to try several KPI and then find the best to optimize. In this case, you wanted to optimize the number of lines, it's definitely not the best as you can see above. If anything try first to get a working solution then a readable one and finally an optimized one where you document why it's optimized so that the readability is maintained.
Here, for instance, is the most optimized version I could come up with. It definitely contains more lines, but also is definitely faster, since I skip all invalid numbers and never do a modulo (only two divisions and two multiplications for the whole program).
public class CoolDude {
public static void main(String[] args) {
final int min = 100;
final int max = 500;
for (int i5 = nextMultiple(min, 5), i11 = nextMultiple(min, 11); i5 <= max || i11 <= max; ) {
if (i5 < i11) {
System.out.printf("Cool - %d%n", i5);
i5 += 5;
} else if (i11 < i5) {
System.out.printf("Dude - %d%n", i11);
i11 += 11;
} else { // i5 == i11
System.out.printf("Cool Dude - %d%n", i5);
i5 += 5;
i11 += 11;
}
}
}
static int nextMultiple(int number, int divisor) {
int roundToLower = (number - 1) / divisor * divisor;
return roundToLower + divisor;
}
}
You could restructure your decision tree such that there will only ever have to be 2 checks (each with 1 operation and 1 comparison) against the number in the loop. Currently, your decision tree requires 2 operations and 2 comparisons in the best case (i is divisible by both 5 and 11) and 4 operations and 4 comparisons in the worst case (i is not divisible by either 5 or 11), but we can reduce that to always be just 2 comparisons and 2 operations, which will result in a more performant loop. In this way, i is only ever tested for divisibility against 5 and 11 one time for each number, so only 2 operations and 2 comparisons will need to be done no matter what the stage of the loop. This is the sort of optimization you should be looking at when trying to optimize a loop.
I also made your print method calls a printf call instead, reducing two print statements into 1. Here is a printf cheat sheet that you can use if you are unfamiliar with it.
Now, doing all this only reduced the size of your code by 1 line, and while I am sure that could be reduced further with some clever use of ternary operators or other methods, as a general rule, measuring code quality by number of lines is a terrible metric, and should never be used, particularly when we are talking about a compiled language like Java. There are a lot of things I could do to the code below that would reduce the line count at the expense of readability and/or performance, but there is no real point to that outside of competitions between programmers, like code golf (but even with that you are competing for the lowest character count, not line count).
Instead of shooting for shorter code, you should instead be striving for the best Big-O notation complexity so that your code is more performant, and fewer lines of code does not necessarily correlate with performance.
public class CoolDude {
public static void main(String[] args) {
for (int i = 100; i <= 500; ++i) {
if (i % 5 == 0) {
if (i % 11 == 0) {
System.out.printf("Cool Dude - %d\n", i);
} else {
System.out.printf("Cool - %d\n", i);
}
} else if (i % 11 == 0) {
System.out.printf("Dude - %d\n", i);
}
}
}
}
IntStream.rangeClosed(100,500).forEach(i->{
if(i%5 == 0 && i%11 == 0) {
System.out.println("Cool Dude - "+i );
} else if (i%5 == 0) {
System.out.println("Cool - "+i );
} else if (i%11 == 0) {
System.out.println("Dude - "+i );
}
});
The below should reduce lines of code, though it does not appear to run faster. It also corrects spacing around the hyphen and perhaps simplifies the logic.
public class CoolDude {
public static void main(String args[]) {
for (int i = 100; i <= 500; ++i) {
StringBuilder coolDude = new StringBuilder(15); //15 chars max "Cool Dude - 495"
if (i % 5 == 0) {
coolDude.append("Cool ".toCharArray());
}
if (i % 11 == 0) {
coolDude.append("Dude ".toCharArray());
}
if (coolDude.length() > 0) {
System.out.println(coolDude.append(("- " + i).toCharArray()));
}
}
}
}
REVISION:
My point was that it was possible to take advantage of being able to do each mod calculation only once each time through the loop. That got lost in trying to save time with StringBuilders and a single line (which, as others pointed out, isn't a worthy goal). I clarified by using print and println instead.
public class CoolDude {
public static void main(String args[]) {
boolean printed = false;
for (int i = 100; i <= 500; ++i, printed = false) {
if (i % 5 == 0) {
System.out.print("Cool ");
printed = true;
}
if (i % 11 == 0) {
System.out.print("Dude ");
printed = true;
}
if (printed) {
System.out.println("- " + i);
}
}
}
}

How do I combine these two while statements into one?

I have two while loops where one is taking the odd numbers between 50 to 100 and the other is taking the even numbers from the same between 50 to 100. It is printing out well and it works but my professor wants me to transform it into one while loop instead of two. I am having trouble with it because I am using the print statement before in order so it fits into when the numbers go in.
int e = 50;
int o = 51;
System.out.print("Even numbers between 50 and 100: 50,");
while (e <= 98){
e += 2;
if (e%2 == 0){
System.out.print(e + ",");
}
}
System.out.print("\nOdd numbers between 50 and 100: 51,");
while (o <= 97){
o+= 2;
if (e%1 == 0) {
System.out.print(o + ",");
}
}
Even numbers between 50 and 100: 50,52,54,56,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,88,90,92,94,96,98,100,
Odd numbers between 50 and 100: 51,53,55,57,59,61,63,65,67,69,71,73,75,77,79,81,83,85,87,89,91,93,95,97,99,
The output looks like this right now, but I need to be able to do it with just one loop instead
If you only want one while loop, and separate lines, you should build your strings and print them afterwards.
Something like:
StringBuilder odds = new StringBuilder();
StringBuilder evens = new StringBuilder();
i = 50;
while(i<100) {
if(i%2 == 1) {
odds.append(i).append(",");
}
else {
evens.append(i).append(",");
}
i++;
}
// remember that odds and evens now probably ends with a ','which you should remove
odds.removeCharAt(odds.size());
evens.removeCharAt(evens.size());
// or do something like the following:
//odds.append(" and nothing more!");
//evens.append(" and nothing more!");
System.out.println("Odd numbers are: ");
System.out.println(odds);
System.out.println("Even numbers are" ");
System.out.println(evens)
Try to increment a counter variable by 1 in each step and use an if statement to check the modulus (%). If it equals 0, then the number is even; if it equals 1, then the number is odd. For printing the separately, you can use two lists or arrays.
int count=50;
StringBuilder odds = new StringBuilder();
StringBuilder evens = new StringBuilder();
while(count<=100)
{
if(count%2==0) // here, the number is even, append this number to even string
evens.append(count).append(",");
else // here, the number is odd, append this number to odds string
odds.append(count).append(",");
count++;
}
// when everything is done, print the strings
// before doing that, you should remove the last comma at the end of these Strings.
// Otherwise, you will have something like this: 93,95,97,
evens.setLength(evens.length() - 1); // to remove the comma at the end
odds.setLength(odds.length() - 1); // to remove the comma at the end
System.out.println("The even numbers are: " + evens.toString());
System.out.println("The odd numbers are: " + odds.toString());
It is much more efficient to use a StringBuilder rather than using += kind of appending for Strings. Take a look at this link:
https://docs.oracle.com/javase/8/docs/api/java/lang/StringBuilder.html
You can use single while loop like this for printing odd and even number.
int e = 50;
while (e <= 98)
{
if (e%2 == 0)
{
System.out.println("even :"+e);
}
else
{
System.out.println("odd :"+e);
}
e++;
}
Just create 2 string output variables and fill them in the loop based on condition
if (i%2==1)
odd_output = odd_output + "," + i.toString
else
even_output = even_output + "," + i.toString
(I might be wrong in Java syntax)
And then just print both resulting strings with any additional info you like
I know it doesn't answer directly the question (although the output is the same) but in 2016 when one want to print a sequence of numbers we do something like that:
public static void main(String[] args) {
int[] evenNumbers = IntStream.rangeClosed(50, 100).filter(i -> i % 2 == 0).toArray();
int[] oddNumbers = IntStream.rangeClosed(50, 100).filter(i -> i % 2 != 0).toArray();
System.out.println("Even numbers between 50 and 100: " + Arrays.toString(evenNumbers));
System.out.println("Odd numbers between 50 and 100: " + Arrays.toString(oddNumbers));
}
If the goal of your exercice is to learn how to use a while loop, my solution is useless. However if your goal is to practice Java as it should be nowadays, I think if reaches the goal.
Here You don't need to maintain Any separate Arrays Or Strings, but a complex conditions
public class EvenOddTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
int num = 50;
System.out.println("Even numbers between 50 and 100: ");
while (num < 100){
if (num%2 == 0){
System.out.print(num + ",");
} else {
System.out.print(num + ",");
}
if( num == 98 ) {
num = 49;
System.out.println();
System.out.println("Odd numbers between 50 and 100: ");
}
num += 2;
}
}
}

"for" loop and perfect numbers [closed]

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 8 years ago.
Improve this question
Have to create program that list all perfect number( sum of factors = number ) 1 - 1000.
this is for a java class, need to only use "for" loops
I have checked my code 100 times and getting no output, I am missing a logical error somewhere, could someone help me out?
public static void main(String[] args)
{
// variables
int total = 0;
final int LIMIT = 1000;
// for loop to test all numbers 1-1000
for(int i = 1; i <= LIMIT; i++)
{
// if statement
if((i != 1) && (total == i - 1))
{
// prints perfect number
System.out.println((i - 1) + " is a perfect number");
// resets total value
total = 0;
}
// gets and add factors as total
for(int divider = 1; divider < i; divider++)
{
if((i % divider) == 0)
{
total += divider;
}
}
}
}
Your big problem is that you only reset total if you find a perfect number. If you don't find a perfect number, you continue adding divisors for the next number to the old total. You need to start fresh for every i.
Rearranging your program in the following way should help:
public static void main(String[] args) {
final int LIMIT = 1000;
for (int i = 0; i <= LIMIT; i++) {
// Declare total here, inside the loop, so values from previous
// iterations are discarded.
int total = 0;
for (/* your code here */) {
// add up divisors
// your code here
}
// compare to i, rather than always computing the total for the
// previous number and comparing to that.
if (/* your code here */) {
// print output
// your code here
}
}
}
You should move total = 0; outside of your if statement. Your total is adding up and never being reset.
I reccomend to split your algorithm to different parts, so you can focus on smaller tasks at time.
Find factors of number i. A method that gets a number and return an arrays of it's factors.
Sum factors together. A simple method that takes an array and returns it's the sum.
Main loop: just check if sum(factors(i)) == i
You can start with the more easy ones (Hint: 2 and 3) and then maybe search for some not-totally-inefficient ways to implement 1
(total == i - 1) will never match when you start with total=0 and i>1.
You were close. Just need to re-evaluate your logic a bit.
public static void main(String[] args) {
// variables
int total = 0;
final int LIMIT = 1000;
// for loop to test all numbers 1-1000
for (int i = 1; i <= LIMIT; i++) {
// gets and add factors first
for (int divider = 1; divider < i; divider++) {
if ((i % divider) == 0) {
total += divider;
}
}
// then check if sum == number
// also just print i instead of - 1
if ((i != 1) && (total == i)) {
// prints perfect number
System.out.println((i) + " is a perfect number");
}
// alway reset when we are done with a number
total = 0;
}
}
for(int i=1;i<1000;i++)
{
int k=0;
for(int j=1;j<i;j++)
{
if(i % j==0)
{
k+=j;
}
}
if(k==i)
{
System.out.println(k);
}
}

Categories