I am working on a program right now and part of it requires me to find the total amount of digits between two integers, I have figured it out for integers that have the same amount of digits, e.g. 1234 and 4980 (both have four digits) but I can't seem to figure it out for the integers that don't have the same amount of digits, i.e. 3 and 5698 (3 only has one digit and 5698 has four). How might I go about this?
Boy, the algorithm is not obvious – your last comment is rather crucial.
Evidently this question boils down to:
For each 'number' between the 2, including both of the edges, count how many digits that number has.
Sum those up.
For your example it's simply (4980 - 1234 + 1) * 4 = 14988.
Sounds like you simply need to for-loop: for (int i = 1234; i <= 4980; i++), and then for each i just figure out how many digits there are and add those.
An straightforward way is to use logarithms. The number of digits in an integer n is (int)Math.log10(n)+1. Assuming you are doing inclusive computations on first thru last it would be as follows:
int sum = 0;
int first = 3;
int last = 3333;
for (int i = first; i <= last; i++) {
sum += Math.log10(i)+1;
}
System.out.println(sum);
prints
12223
But a more efficient and perhaps less obvious way it to forgo logs and simply compute in pieces. This will reduce number of iterations of the loop. This works by computing the number of digits and the power in increments. I put in print statements so you can see the progression.
int digits = 1;
int power = 10;
int limit = last;
sum = 0;
while(power < limit) {
if (power > first) {
sum += (power - first) * digits;
System.out.println(power + " " + first + " " + digits + " : partial running sum = " + sum);
first = power;
}
digits++;
power*= 10;
}
sum += (limit - power/10 + 1)*digits;
System.out.println(limit + " " + power/10 + " " + digits + " : partial running sum = " + sum);
System.out.println(sum);
prints
10 3 1 : partial running sum = 7
100 10 2 : partial running sum = 187
1000 100 3 : partial running sum = 2887
3333 1000 4 : final sum = 12223
12223
Related
This question already has answers here:
Differences between System.out.println() and return in Java
(4 answers)
Closed 3 years ago.
I have to write a method int sumBeyond(int k) to find the least n such that the sum of the natural numbers smaller than n exceeds k.
However, when I try to test the method it doesn't return any value.
public static int sumBeyond(int k){
int i=1;
int sum=0;
while(i<k){
sum=sum+i;
i=i+1;
}
return sum;
}
I tried calling the function this way, in the main method:
sumBeyond(100);
int sum100 = sumBeyond(100);
System.out.println("Sum is " + sum100);
Then small improvements:
public static int sumBeyond(int k) {
int i = 1;
int sum = 0;
while (i < k) {
sum += i;
++i;
}
return sum;
}
public static int sumBeyond(int k) {
int sum = 0;
for (int i = 1; i < k; ++i) {
sum += i;
}
return sum;
}
public static int sumBeyond(int k) {
// return (k - 1) * (1 + k - 1) / 2;
return (k - 1) * k / 2;
}
To solve the problem stated:
Find n such that sum upto n-1 >= k' where k' is k - 1.
Sum upto n-1 is (n - 1) * n / 2 >= k'
So we get:
x² - x - 2k'
------------ >= 0
2
Solution for = 0:
a = 1/2
b = -1/2
c = -2k'
_________
-b +/- V b² - 4ac
x = ------------------
2a
x = 1/2 +/- sqrt(1/4 + 4k'/4) =
= 1/2 +/- 1/2 . sqrt(1 + 4k')
Positive x
x = 1/2 + 1/2 . sqrt(4k' + 1)
public static int sumBeyond(int k) {
double x = (Math.sqrt(4 * (k-1) + 1) + 1) / 2;
return (int) Math.ceil(x);
}
The solution should be given the math as comment.
If I got your question right, you want to find the least n such that the sum of the natural numbers smaller than n exceeds k and thus, you shouldn't return the sum itself, because it is not n but needs to be calculated in order to find the smallest n.
You can do it the following way:
public static int sumBeyond(int k) {
int n = 0;
int sum = 0;
for (int i = 0; i < k; i++) {
// provide an intermediate sum (the one before this step) for logging purpose
int intermediateSum = sum;
// sum up
sum += i;
// set the return value to the current "natural number"
n = i;
// print some detailed debug log
System.out.println("sum:\t" + sum +
" (" + intermediateSum + " + " + i + ")\t——>\tn = " + n);
// exit the loop if the sum is greater than k
if (sum >= k) {
break;
}
}
return n + 1;
}
Calling it in a main like this
public static void main(String[] args) {
int k = 100;
System.out.println("The least n" +
+ "such that the sum of the natural numbers smaller than n exceeds "
+ k + " is " + sumBeyond(k));
}
will print
sum: 0 (0 + 0) ——> n = 0
sum: 1 (0 + 1) ——> n = 1
sum: 3 (1 + 2) ——> n = 2
sum: 6 (3 + 3) ——> n = 3
sum: 10 (6 + 4) ——> n = 4
sum: 15 (10 + 5) ——> n = 5
sum: 21 (15 + 6) ——> n = 6
sum: 28 (21 + 7) ——> n = 7
sum: 36 (28 + 8) ——> n = 8
sum: 45 (36 + 9) ——> n = 9
sum: 55 (45 + 10) ——> n = 10
sum: 66 (55 + 11) ——> n = 11
sum: 78 (66 + 12) ——> n = 12
sum: 91 (78 + 13) ——> n = 13
sum: 105 (91 + 14) ——> n = 14
The least n such that the sum of the natural numbers smaller than n exceeds 100 is 15
I really hope I got this right, still not sure...
Oh, and if 0 is not a natural number, start iterating at 1.
So as has been noted above, the issue was not that your method was not returning something, but that you were doing nothing with what was returned. Also, as noted above, you were focused on finding the sum, but that is not actually what the question asked.
I am sympathetic to your use of a while loop here since it may not execute at all and since you don't know a priori how many times it will run. So I rewrote it to check the right things and adapted the main from deHaar to exercise it. That allowed me to hand check the answers, because some of the cases of equality and need for "numbers less than" rather than "numbers less than or equal to" were subtle.
The math teacher in me really likes the quadratic formula approach from Joop Eggen; it's just harder to get right (and indeed, if I were going to do it, I would end up testing that it's consistent with what I have here).
public class ShadesOfLittleGauss {
public static int sumBeyond(int k) {
int i = 1; //have summed (trivially) all natural numbers less than 1 so far
int sum = 0;
while (sum <= k) { //needs to exceed, so <=
sum = sum + i;
i = i + 1;
}
return i;
}
public static void main(String[] args) {
for (int k = -1; k < 10; k++) {
System.out.println("The least number " +
"such that the sum of the natural numbers smaller than n exceeds " +
k + " is " + sumBeyond(k));
}
}
}
output (you can hand check these are correct as stated):
The least number such that the sum of the natural numbers smaller than n exceeds -1 is 1
The least number such that the sum of the natural numbers smaller than n exceeds 0 is 2
The least number such that the sum of the natural numbers smaller than n exceeds 1 is 3
The least number such that the sum of the natural numbers smaller than n exceeds 2 is 3
The least number such that the sum of the natural numbers smaller than n exceeds 3 is 4
The least number such that the sum of the natural numbers smaller than n exceeds 4 is 4
The least number such that the sum of the natural numbers smaller than n exceeds 5 is 4
The least number such that the sum of the natural numbers smaller than n exceeds 6 is 5
The least number such that the sum of the natural numbers smaller than n exceeds 7 is 5
The least number such that the sum of the natural numbers smaller than n exceeds 8 is 5
The least number such that the sum of the natural numbers smaller than n exceeds 9 is 5
UPDATE: I did solve the quadratic and came up with the following which agrees with the simpler approach.
public static int sumBeyond2(int k) {
if (k < 0) { //do not take squareroots of negatives
return 1;
}
double x = -1.0 / 2 + Math.sqrt(1 + 8 * k) / 2; //from solving quadratic inequality n(n+1)/2.0 > k
if (Math.abs(Math.round(x) - x) < 0.0000001) { //special case, it is an integer, so ceil won't reliably add 1
return 1 + 1 + (int) Math.round(x);
}
return 1 + (int) Math.ceil(x); //adding 1 because of wording, integers less than, ceil because needs to exceed k
}
My problem is as follows; for number N, I need to find out what is the largest value I can count to, when each digit can be used N times.
For example if N = 5, the largest value is 12, since at that point the digit 1 has been used 5 times.
My original approach was to simply iterate through all numbers and keep a tally of how many times each digit has been used so far. This is obviously very inefficient when N is large, so am looking for advice on what would be a smarter (and more efficient) way to achieve this.
public class Counter {
private static Hashtable<Integer, Integer> numbers;
public static void main(String[] args){
Counter c = new Counter();
c.run(9);
}
public Counter() {
numbers = new Hashtable<Integer, Integer>();
numbers.put(0, 0);
numbers.put(1, 0);
numbers.put(2, 0);
numbers.put(3, 0);
numbers.put(4, 0);
numbers.put(5, 0);
numbers.put(6, 0);
numbers.put(7, 0);
numbers.put(8, 0);
numbers.put(9, 0);
}
public static void run(int maxRepeat) {
int keeper = 0;
for(int maxFound = 0; maxFound <= maxRepeat; maxFound++) {
keeper++;
for (int i = 0; i < Integer.toString(keeper).length(); i++) {
int a = Integer.toString(keeper).charAt(i);
//here update the tally for appropriate digit and check if max repeats is reached
}
}
System.out.println(keeper);
}
}
For starters, rather than backing your Counter with a Hashtable, use an int[] instead. When you know exactly how many elements your map has to have, and especially when the keys are numbers, an array is perfect.
That being said, I think the most effective speedup is likely to come from better math, not better algorithms. With some experimentation (or it may be obvious), you'll notice that 1 is always the first digit to be used a given number of times. So given N, if you can find which number is the first to use the digit 1 N+1 times, you know your answer is the number right before that. This would let you solve the problem without actually having to count that high.
Now, let's look at how many 1's are used counting up to various numbers. Throughout this post I will use n to designate a number when we are trying to figure out how many 1's are used to count up to a number, whereas capital N designates how many 1's are used to count up to something.
One digit numbers
Starting with the single-digit numbers:
1: 1
2: 1
...
9: 1
Clearly the number of 1's required to count up to a one-digit number is... 1. Well, actually we forgot one:
0: 0
That will be important later. So we should say this: the number of 1's required to count up to a one-digit number X is X > 0 ? 1 : 0. Let's define a mathematical function f(n) that will represent "number of 1's required to count up to n". Then
f(X) = X > 0 ? 1 : 0
Two-digit numbers
For two-digit numbers, there are two types. For numbers of the form 1X,
10: 2
11: 4
12: 5
...
19: 12
You can think of it like this: counting up to 1X requires a number of 1's equal to
f(9) (from counting up to 9) plus
1 (from 10) plus
X (from the first digits of 11-1X inclusive, if X > 0) plus
however many 1's were required to count up to X
Or mathematically,
f(1X) = f(9) + 1 + X + f(X)
Then there are the two-digit numbers higher than 19:
21: 13
31: 14
...
91: 20
The number of 1's required to count to a two-digit number YX with Y > 1 is
f(19) (from counting up to 19) plus
f(9) * (Y - 2) (from the 1's in numbers 20 through (Y-1)9 inclusive - like if Y = 5, I mean the 1's in 20-49, which come from 21, 31, 41) plus
however many 1's were required to count up to X
Or mathematically, for Y > 1,
f(YX) = f(19) + f(9) * (Y - 2) + f(X)
= f(9) + 1 + 9 + f(9) + f(9) * (Y - 2) + f(X)
= 10 + f(9) * Y + f(X)
Three-digit numbers
Once you get into three-digit numbers, you can kind of extend the pattern. For any three-digit number of the form 1YX (and now Y can be anything), the total count of 1's from counting up to that number will be
f(99) (from counting up to 99) plus
1 (from 100) plus
10 * Y + X (from the first digits of 101-1YX inclusive) plus
however many 1's were required to count up to YX in two-digit numbers
so
f(1YX) = f(99) + 1 + YX + f(YX)
Note the parallel to f(1X). Continuing the logic to more digits, the pattern, for numbers which start with 1, is
f(1[m-digits]) = f(10^m - 1) + 1 + [m-digits] + f([m-digits])
with [m-digits] representing a sequence of digits of length m.
Now, for three-digit numbers ZYX that don't start with 1, i.e. Z > 1, the number of 1's required to count up to them is
f(199) (from counting up to 199) plus
f(99) * (Z - 2) (from the 1's in 200-(Z-1)99 inclusive) plus
however many 1's were required to count up to YX
so
f(ZYX) = f(199) + f(99) * (Z - 2) + f(YX)
= f(99) + 1 + 99 + f(99) + f(99) * (Z - 2) + f(YX)
= 100 + f(99) * Z + f(YX)
And the pattern for numbers that don't start with 1 now seems to be clear:
f(Z[m-digits]) = 10^m + f(10^m - 1) * Z + f([m-digits])
General case
We can combine the last result with the formula for numbers that do start with 1. You should be able to verify that the following formula is equivalent to the appropriate case given above for all digits Z 1-9, and that it does the right thing when Z == 0:
f(Z[m-digits]) = f(10^m - 1) * Z + f([m-digits])
+ (Z > 1) ? 10^m : Z * ([m-digits] + 1)
And for numbers of the form 10^m - 1, like 99, 999, etc. you can directly evaluate the function:
f(10^m - 1) = m * 10^(m-1)
because the digit 1 is going to be used 10^(m-1) times in each of the m digits - for example, when counting up to 999, there will be 100 1's used in the hundreds' place, 100 1's used in the tens' place, and 100 1's used in the ones' place. So this becomes
f(Z[m-digits]) = Z * m * 10^(m-1) + f([m-digits])
+ (Z > 1) ? 10^m : Z * ([m-digits] + 1)
You can tinker with the exact expression, but I think this is pretty close to as good as it gets, for this particular approach anyway. What you have here is a recursion relation that allows you to evaluate f(n), the number of 1's required to count up to n, by stripping off a leading digit at each step. Its time complexity is logarithmic in n.
Implementation
Implementing this function is straightforward given the last formula above. You can technically get away with one base case in the recursion: the empty string, i.e. define f("") to be 0. But it will save you a few calls to also handle single digits as well as numbers of the form 10^m - 1. Here's how I'd do it, omitting a bit of argument validation:
private static Pattern nines = Pattern.compile("9+");
/** Return 10^m for m=0,1,...,18 */
private long pow10(int m) {
// implement with either pow(10, m) or a switch statement
}
public long f(String n) {
int Z = Integer.parseInt(n.substring(0, 1));
int nlen = n.length();
if (nlen == 1) {
return Z > 0 ? 1 : 0;
}
if (nines.matcher(n).matches()) {
return nlen * pow10(nlen - 1);
}
String m_digits = n.substring(1);
int m = nlen - 1;
return Z * m * pow10(m - 1) + f_impl(m_digits)
+ (Z > 1 ? pow10(m) : Z * (Long.parseLong(m_digits) + 1));
}
Inverting
This algorithm solves the inverse of the the question you're asking: that is, it figures out how many times a digit is used counting up to n, whereas you want to know which n you can reach with a given number N of digits (i.e. 1's). So, as I mentioned back in the beginning, you're looking for the first n for which f(n+1) > N.
The most straightforward way to do this is to just start counting up from n = 0 and see when you exceed N.
public long howHigh(long N) {
long n = 0;
while (f(n+1) <= N) { n++; }
return n;
}
But of course that's no better (actually probably worse) than accumulating counts in an array. The whole point of having f is that you don't have to test every number; you can jump up by large intervals until you find an n such that f(n+1) > N, and then narrow down your search using the jumps. A reasonably simple method I'd recommend is exponential search to put an upper bound on the result, followed by a binary search to narrow it down:
public long howHigh(long N) {
long upper = 1;
while (f(upper + 1) <= N) {
upper *= 2;
}
long lower = upper / 2, mid = -1;
while (lower < upper) {
mid = (lower + upper) / 2;
if (f(mid + 1) > N) {
upper = mid;
}
else {
lower = mid + 1;
}
}
return lower;
}
Since the implementation of f from above is O(log(n)) and exponential+binary search is also O(log(n)), the final algorithm should be something like O(log^2(n)), and I think the relation between N and n is linear enough that you could consider it O(log^2(N)) too. If you search in log space and judiciously cache computed values of the function, it might be possible to bring it down to roughly O(log(N)). A variant that might provide a significant speedup is sticking in a round of interpolation search after determining the upper bound, but that's tricky to code properly. Fully optimizing the search algorithm is probably a matter for another question though.
This should be more efficient. Use integer array of size 10 to keep the count of digits.
public static int getMaxNumber(int N) {
int[] counts = new int[10];
int number = 0;
boolean limitReached = false;
while (!limitReached) {
number++;
char[] digits = Integer.toString(number).toCharArray();
for (char digit : digits) {
int count = counts[digit - '0'];
count++;
counts[digit - '0'] = count;
if (count >= N) {
limitReached = true;
}
}
}
return number;
}
UPDATE 1: As #Modus Tollens mentioned initial code has a bug. When N = 3 it returns 11, but there are four 1s between 1 and 11. The fix is to check if limit is breached count[i] > N on given number, previous number should be return. But if for some i count[i] == N for other j count[j] <= N, the actual number should be returned.
Please see corresponding code below:
public static int getMaxNumber(int N) {
int[] counts = new int[10];
int number = 0;
while (true) {
number++;
char[] digits = Integer.toString(number).toCharArray();
boolean limitReached = false;
for (char digit : digits) {
int count = counts[digit - '0'];
count++;
counts[digit - '0'] = count;
if (count == N) {
//we should break loop if some count[i] equals to N
limitReached = true;
} else if (count > N) {
//previous number should be returned immediately
//, if current number gives more unique digits than N
return number - 1;
}
}
if (limitReached) {
return number;
}
}
}
UPDATE 2: As #David Z and #Modus Tollens mentioned, in case if N=13, 30 should be returned, ie, algo stops when N is breached but not reached. If this is initial requirement, the code will be even simpler:
public static int getMaxNumber(int N) {
int[] counts = new int[10];
int number = 0;
while (true) {
number++;
char[] digits = Integer.toString(number).toCharArray();
for (char digit : digits) {
int count = counts[digit - '0'];
count++;
counts[digit - '0'] = count;
if (count > N) {
return number - 1;
}
}
}
}
Write statements that can be used in a Java Program two integers and display the number of even integers that lie between them. For example, the number of even integers that lie between 12 and 5 are 4
So far below is what i have.... the program outputs all the numbers between the two integers, and not the actual number of even integers.
Can someone please help / tell me what i am doing wrong ?
import java.util.Scanner;
public class evenNumberPrinter {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
System.out.println("Enter the smaller integer");
int numOne = keyboard.nextInt();
System.out.println("Enter the larger integer");
int numTwo = keyboard.nextInt();
for (int i = numOne; i <= numTwo; i++) {
System.out.println(i + " ");
}
}
}
to calculate count of even numbers you don't have to use for loop, here is the formula:
static long evenCount(long a, long b) {
return ((Math.abs(a - b) + 1) >>> 1) + ((~((a & 1) | (b & 1))) & 1);
}
some clarification:
zero (0) is even number
count of even numbers obviously depends on distance between two values, lets pull some data:
0-0 - 1 number, distance 0 (0)
0-1 - 1 number, distance 1
0-2 - 2 numbers, distance 2 (0, 2)
0-3 - 2 numbers, distance 3
0-4 - 3 numbers, distance 4 (0, 2, 4)
0-5 - 3 numbers, distance 5
0-6 - 4 numbers, distance 6 (0, 2, 4, 6)
1-1 - no even, distance 0
1-2 - 1 number, distance 1 (2)
so, count of even numbers is determined by (distance+1)/2 plus one if both numbers are even
so, if we take distance Math.abs(a-b) + 1 divide it by two (>>>1) and then add 1 if and only if both numbers are even (a&1)==0
Another solution is to use pure math:
round the smaller number to the next even number (e.g. 5 to 6)
round the bigger number to the previous even number (e.g. 13 to 12)
subtract from the bigger rounded the smaller, e.g. 12-6 = 6
since even numbers are every second, divide it by 2 plus add one to count the first number of the range as well, that is 3+1=4
That is:
public static void main(final String[] args) {
final int number1=1;
final int number2=6;
int min=Math.min(number1, number2);
int max=Math.max(number1, number2);
min=min+min%2; // round up
max=max-max%2; // round down
final int evens=(max-min)/2+1; // even range plus the first number
System.out.println(evens); // Look ma, no loops
}
Edited to include explanation
Your for loop is doing nothing more than printing each number between numOne and numTwo. What you want to do is check to see if i is even or odd which can be accomplished using the modulus operator if i modulus 2 equals zero, then that number is even, and you should increment a counter variable each time this is true.
Change your for loop to something like this:
int evenCounter = 0;
for (int i = numOne; i < numTwo; i++){
if (i % 2 == 0){
System.out.print(i + " ");
evenCounter++;
}
}
System.out.println("There are " + evenCounter + " even numbers between " +
numOne + " and " + numTwo);
A little more optimal solution (if you want to print the numbers). Testing for parity (odd vs even) can be done only once, before entering the loop. Afterwards, just stay on even numbers by incrementing by 2.
int n = numOne;
int evenCount = 0;
if ((n%2)==1) { n++; }
while (n <= numTwo) {
System.out.println(n);
n += 2;
evenCount ++;
}
System.out.println( "There are " + evenCount + " even numbers between " + numOne + " and " + numTwo );
However, if your goal is only to determine how many there are (not print them), this is not optimal. A mathematical solution will be much faster.
int n = 0; //this is your counter
for (int i = numOne; i < numTwo; i++) { //use < numTwo instead of <= numTwo
//so it doesn't count numTwo as an int between your range
if (i%2 == 0) {n++;} //checks to see if number is even
// if it is, it adds one to the counter and moves on
}
System.out.println("there are " +n+ "even numbers between " +numOne+ " and " +numTwo); //prints out how many even ints were counted.
I have an array of length N=10^5 For each index 1<=i<=n I have to calculate the difference between A[j]-A[i] and (j-i) is prime and j>i
Here is my code:
for(int i=1;i<=n;i++){
for(int j=0;j<prime.size();j++){
int x = prime.get(j);
if(x+i>n) break;
ans+= A[x+i]-A[i];
}
}
How should i make this work even faster ? I think the time complexity is O(N*prime.size)
First, I will rephrase your question so that it states what I believe you want to achieve. You are probably looking for the sum of the differences of the form A[j]-A[i], where (j-i) is a "positive" prime and 1<=i<j<=N. With this statement in mind...
We count the number of times A[k] is added to the sum (denoted by p) and the number of times A[k] is subtracted from the sum (denoted by m). Well, m is equal to the number of primes in the interval [1,N-k], while p is equal to the number of primes in the interval [1,k-1]. If you don't believe me, simulate step-by-step what your code does. Then you can do:
S = 0
for k = 1 to N do
S = S + (p(k) - m(k)) * A[k]
endfor
Now, we need to find a way to determine p and m efficiently for each k in the interval [1,N]. I see you have already constructed what seems to be an ordered list of primes. So, to answer a query of the form 'how many primes in the interval [1,t]?' you could perform a binary search on that list for t. This would get the complexity down to O(N*log(prime.size)).
As an alternative, you can pre-compute the answers to the queries of the form 'how many primes in the interval [1,t]?'. You need an extra array nrPrimesLessThan of size N to keep the results, doing something like this to compute its values:
count = 0
for i = 1 to N do
if i < prime.get(count) then
nrPrimesLessThan[i] = count
else
count = count + 1
nrPrimesLessThan[i] = count
endif
endfor
The pre-computation part takes O(N) steps, but now one query takes O(1) steps, thus the calculating the sum takes O(N) steps. Overall, linear time in N.
Judging from your code example, you want to sum the differences of all value pairs in the array for which the difference of the indices is prime. You've got already an array of primes.
The diagram below shows how the elements get subtracted and added:
0 1 2 3 4 5 6 7 8 9
- + + + + 0
- + + + + 1
- + + + + 2
- + + + 3
- + + + 4
- + + 5
- + + 6
- + 7
- 8
- 9
A + means an element is added to the overall sum. A - means the element is subtracted from the sum. This is not a single subtraction; the subtraction happens for each addition to its left, so A[0] is subtracted 4 times. It is never added.
On the other hand, A[9] is never subtracted, but added four times. In general, each element is subtracted as many times as there are plusses in a row and it is added as many times as there are plusses in a columns. There is a symmetry here:
add[i] = sub[N - i - 1]
for zero-based indices. What is the value of add[i]? It is the number of primes that are smaller or equal to i.
Here's a code example where the add array is called m:
int psum2(const int A[], int n)
{
int sum = 0;
int m[n];
int j = 0;
int k = 0;
for (int i = 0; i < n; i++) {
if (i == prime[j]) {
k++;
j++;
}
m[i] = k;
}
for (int i = 0; i < n; i++) {
sum += (m[i] - m[n - i - 1]) * A[i];
}
return sum;
}
The array m is always the same and can be precalculated if you need to perform the sum more often. The algorithm is O(n).
The problem is also unrelated to primes at its core. The method above works for all conditional sums of differences where the difference of the indices must be conteined in a certain set of numbers.
I have seen this question asked a few times, but all of the responses have included functionality that I haven't learned yet in this class and am I sure there must be a way to do it with only what I have learned. No arrays, etc... just loops and prior. I am not really looking for the answer, but just some direction. I have included the code I have already done. The program needs to be able to hand negative numbers, the sum and then print in the proper order. Right now my code does everything except print in the proper order. I understand why it is printing in reverse order (because the loop gets rid of and then prints the last number in the int), but I can't seem to figure out a way to change it. I have tried converting it to a string, char and just can't get it. Please take a look, and provide some guidance if you don't mind. thank you in advance.
public static void main(String[] args) {
int num;
int sum;
int temp;
System.out.print("Enter an integer, positive or negative: ");
num = keyboard.nextInt();
System.out.println();
if (num < 0)
num = -num;
sum = 0;
while (num > 0) {
temp = num;
sum = sum + num % 10; //Extracts the last digit and adds it to the sum
num = num / 10; //removes the last digit
System.out.print(temp % 10 + " ");
}
System.out.println(" and the sum is " + sum);
}
}
Not knowing what they've taught you in class so far, an easy albeit inefficient thing to do is to recreate the number as string.
String numbers = "";
while (num > 0) {
temp = num;
sum = sum + num % 10; //Extracts the last digit and adds it to the sum
num = num / 10; //removes the last digit
// System.out.print(temp % 10 + " ");
numbers = (temp % 10) + " " + numbers;
}
System.out.println(numbers + "and the sum is " + sum);
You were already grabbing the ones digit with (temp % 10) and then right shifting the original number with num = num / 10. There are other data structures you could use like a Stack or a LinkedList that are more natural to use in a situation like yours, or you could use a StringBuilder to append the digits to the end and then use the reverse() method to get them back in the correct order, but those data structures probably come after Arrays which you mentioned you didn't know.
Given those constraints, I used String concatenation. In general here is what happens:
String numbers = "";
num = 123;
digit = num % 10; // digit=3
num /= 10; // num=12
numbers = digit + " " + numbers; // numbers="3 " uses old value on right side of the equals
// next iteration
digit = num % 10; // digit=2
num /= 10; // num=1
numbers = digit + " " + numbers; // numbers="2 3 " see how the digit is put to the left of the old value
// last iteration
digit = num % 10; // digit=1
num /= 10; // num=0
numbers = digit + " " +numbers; // numbers="1 2 3 " notice there is an extra space at the end which is ok for your example
Set a counter, loop num/10, if result>0 counter++. In the end, counter+1 will be the number of digits
System.out.println("Please enter numbers: ");
int number_entered = input.nextInt();
int sum = 0;
String reserve = "";
if (number_entered < 0 ) {
number_entered = number_entered * -1;
}
for (number_entered = number_entered; number_entered > 0; number_entered/=10){
int lastdgt = number_entered%10;
sum += lastdgt;
reserve = lastdgt + " " + reserve + " ";
}
System.out.println(reserve);
System.out.println("The sum is = " + sum );
}
}