Recently i attended an interview where i was asked to write a function to find a term in a number and the number of times it occurs.
Lets say term = 51, number = 164518351, so 51 does exits in number and it occurs for 2 times, so return 2.
My Solution - Convert the number and term into string and , replace term string with "A" in the number string and then finally count the number of "A" in the number string. He asked me to solve without using strings, so i gave an array approach.
But he said that i cannot use arrays as well. so i want to know if there are other ways to do this ? I don't want the exact code or algo i just want to know various approaches we can take to solve this problem in minimum time complexity.
you can try something like this
int term_count = 0;
while(number > 0){
if(number % 100 == term)
term_count++;
number = number/10
}
This will check if the last two digits of the number is equal to the term, and continue doing so ignoring every unit digits of the number.
something like this
164518351 % 100 == 51
16451835 % 100 == 51
1645183 % 100 == 51
164518 % 100 == 51
....
of course, here i know that the term is two digits and so i mod by 100. if you don't know that, you can find the number of digits in the term and then mod number by
10^(num_of_digits_in_term)
you can find the number of digits like this
int tempTerm = term, termDigitCount = 0;
while(tempTerm > 0){
termDigitCount++;
tempTerm /= 10;
}
// 51 > 0 -> termDigitCount = 1
// 1 > 0 -> termDigitCount = 2
// 0 > 0 -> exit while loop
and in the end if the term_count is 0, then there is no occurrence of the term in the number
Hope this helps.
P.S - the solution may not be syntactically correct since OP does not want an exact answer. just the logic.
Related
So I have this line of code. It gives me output [6,28].
Do you guys know why? I dont know what kind of numbers was someone trying to print.
System.out.println( IntStream.range(1,30).filter(n -> IntStream.range(1,n).filter(i->n%i == 0).sum() ==n)
.boxed().collect(Collectors.toList()));
IntStream.range(1,n).filter(i -> n % i == 0).sum() == n
calculates all the divisors of n by checking if n divided by the potential divisor has no remainder (i -> n % i == 0). All divisors are then summed and compared with n itself.
IntStream.range(1,30).filter(n -> ...).boxed().collect(Collectors.toList())
Just does what I described above for the numbers between 1 and 30 and only keeps those where the comparison is true. It therefore calculates all the numbers between 1 and 30 where the divisors sum to the number itself. Those are called perfect numbers. The first two are 6 and 28, followed by 496, ...
This program is essentially a game where the user must enter numbers to see which numbers are good: numbers with an even number of even digits, and an odd number of odd digits.
So first of all, the program ends when I enter a one digit number, which is not intentional. I assume that has something to do with the while being while (n > 0). There also is likely an issue with the if (numEven % 2 == 0......) because the print results seem almost random, with a number being good and the same number not being good sometimes.
Honestly, I am lost at this point. Thank you so much in advance for any help.
UPDATE: This code is working how I want it to, I just wanted to thank everybody who helped out! It's my first semester of computer science class, so I'm still rather new at this...excuse my mistakes that were likely pretty stupid :)
package quackygame;
import java.util.Scanner;
public class QuackyGame
{
public static void main(String[] args)
{
System.out.println("Welcome to the Number Game!"
+ " Try to figure out the pattern "
+ "in the numbers that Wallace likes!");
Scanner scan = new Scanner (System.in);
int n;
int numEven = 0;
int numOdd = 0;
boolean isEven;
do
{
System.out.print("Enter a number > 0: ");
n = scan.nextInt();
while (n > 0)
{
if (n % 2 == 0)
{
//n is even
isEven = true;
numEven++;
}
else
{
//n is odd
isEven = false;
numOdd++;
}
n /= 10;
}
//if numEven is even and numOdd is odd
if (numEven % 2 == 0 && numOdd % 2 == 1)
System.out.println("Wallace liked your number!");
else
{
System.out.println("Wallace didn't like your number.");
}
numEven = 0;
numOdd = 0;
}
while (n >= 0);
}
}
There are a few core issues in the code based on the desired results that you described. The most glaring issue I see is that you intend for the game to essentially "start from scratch" at the beginning of each round, but you never actually reset the numEven and numOdd variables. This is the source of your print results seeming random. For example, if you started a game and input the number:
34567
The game would process the number and say that it is a favorable number because it is odd, has an odd number of odd digits (3), and has an even number of even digits (2). However, upon playing the game again, it would execute the same code without setting the variables back to 0, which means that upon entering:
34567
The game would process this number as a bad number because the accumulated value of odd digits would be 6 instead of 3 (since 3 the first time + 3 the second time results in 6), and 6 is even. So what we want to do is this:
...
int n;
do
{
int numEven = 0;
int numOdd = 0;
System.out.print("Enter a number: ");
n = scan.nextInt();
...
By placing the numEven and numOdd declarations inside of the "do" block, they are local variables which only exist for the duration of the do block. We could also do something as simple as this:
...
else
{
System.out.println("Wallace didn't like your number.");
}
numEven = 0;
numOdd = 0;
}
while (n > 0);
...
Just resetting the values will help us to keep track of the actual intended values of numOdd and numEven more consistently.
With regard to the program closing when you input a single digit number, I'm not sure. That doesn't make sense because since it is a do-while loop it should at least execute once, and issue one of the print statements. I'm loading this code into my IDE right now to give it a run through. I'll update my answer if I find something.
-EDIT-: Upon reading your question again, it seems that you may not be suggesting that the program closes before actually completing any of its functions, but simply that it closes at all. The reason for the closing of the program is that you are performing an integer division arithmetic function where you probably want to be using a different type of number. Let me explain:
In normal human counting, we have our natural set of numbers which have no decimal points. They usually start like this:
1, 2, 3, 4, 5 ...
Then we have a separate set of numbers for math where we operate with more precision:
0.5, 1.4232, 3.142 ...
When we are talking about numbers with normal human language, we assume that dividing 1 by 2 results in 0.5. However, computers do not implicitly know this. In order for a computer to reach the conclusion "0.5" from the division of 1 by 2, you need to explicitly tell it that it should use a certain type of number to produce that output.
The "normal" numbers I referenced earlier are most loosely related to the integer in programming. It's basically a number without a decimal point. What that means is that whenever you divide two integers together, you always get another integer as the result. So if you were to divide 1 by 2, the computer would not interpret the result as 0.5 because that number has a decimal. Instead, it would round it down to the nearest integer, which in this case is 0.
So for a more specific example referencing the actual question at hand, let's say we input the number 5 into our program. It goes through all of the calculations for odds and evens, but eventually gets to this line:
n /= 10
This is where things get funky. We are dividing two integers, but their result does not come out as a perfect integer. In this case, the result of 5 / 10 is again 0.5. But for the computer, since we are dividing two integers, the result 0.5 just won't do, so after rounding down to the nearest integer we get 0. At this point, there is one fatal mistake:
(while n > 0);
When we perform this check, we get false and the while loop ends. Why? Because after performing n /= 10, n becomes 0. And 0 is not greater than 0.
How can we fix this? The best thing to do is probably just use a floating point number to perform the calculations. In Java, this is pretty easy. All we really have to do is:
n /= 10.0
When Java sees that we are dividing by 10.0, which is not an integer, it automatically converts "n" to a floating point number to divide by 10.0. In this case then, if n is 5, our result in dividing 5 by 10.0 will be 0.5. Then, when we run:
(while n > 0);
This becomes true! And the loop does not break.
I am going to put all of these changes into my IDE just to confirm that everything is working as intended for me. I would suggest you give it a try too to see if it fixes your problems.
Hope this helps.
You are increasing numEven or numOdd count each time you input a number, and then you use if (numEven % 2 == 0 && numOdd % 2 == 1) , it is random because if you put number 33 for the first time => numOdd = 1; => true => "Wallace likes" , but next time you put 33 for the second time => numOdd = 2; => false => "Wallace doesnt like".
Edit* Maybe you wanted something like this?
public static void main(String[] args)
{
System.out.println("Welcome to the Number Game!"
+ " Try to figure out the pattern "
+ "in the numbers that Wallace likes!");
Scanner scan = new Scanner (System.in);
int n;
boolean isEven;
do
{
System.out.print("Enter a number: ");
n = scan.nextInt();
//if 0, you leave the loop
if(n==0) {
System.out.println("You pressed 0, have a nice day");
break;
}
if (n % 2 == 0)
{
//it is even
isEven = true;
}
else
{
//it is not even
isEven = false;
}
//if even then he likes it, otherwise he does not
if (isEven)
System.out.println("Wallace liked your number!");
else
{
System.out.println("Wallace didn't like your number.");
}
}
//put any contition here, lets say if you press 0 , you leave the loop
while (n != 0);
}
Sorry for a possible duplicate post, I saw many similar topics here but none was exactly I needed. Before actually posting a question I want to explicitly state that this question is NOT A HOMEWORK.
So the question is: how to convert a large integer number into binary representation? The integer number is large enough to fit in primitive type (Java long cannot be used). An input might be represented as a string format or as an array of digits. Disclaimer, This is not going to be a solution of production level, so I don't want to use BigInteger class. Instead, I want to implement an algorithm.
So far I ended up with the following approach:
Input and output values represented as strings. If the last digit of input is even, I prepend the output with "0", otherwise - with "1". After that, I replace input with input divided by 2. I use another method - divideByTwo for an arithmetical division. This process runs in a loop until input becomes "0" or "1". Finally, I prepend input to the output. Here's the code:
Helper Method
/**
* #param s input integer value in string representation
* #return the input divided by 2 in string representation
**/
static String divideByTwo(String s)
{
String result = "";
int dividend = 0;
int quotent = 0;
boolean dividendIsZero = false;
while (s.length() > 0)
{
int i = 1;
dividend = Character.getNumericValue(s.charAt(0));
while (dividend < 2 && i < s.length())
{
if (dividendIsZero) {result += "0";}
dividend = Integer.parseInt(s.substring(0, ++i));
}
quotent = dividend / 2;
dividend -= quotent * 2;
dividendIsZero = (dividend == 0);
result += Integer.toString(quotent);
s = s.substring(i);
if (!dividendIsZero && s.length() != 0)
{
s = Integer.toString(dividend) + s;
}
}
return result;
}
Main Method
/**
* #param s the integer in string representation
* #return the binary integer in string representation
**/
static String integerToBinary(String s)
{
if (!s.matches("[0-9]+"))
{
throw new IllegalArgumentException(s + " cannot be converted to integer");
}
String result = "";
while (!s.equals("0") && !s.equals("1"))
{
int lastDigit = Character.getNumericValue(s.charAt(s.length()-1));
result = lastDigit % 2 + result; //if last digit is even prepend 0, otherwise 1
s = divideByTwo(s);
}
return (s + result).replaceAll("^0*", "");
}
As you can see, the runtime is O(n^2). O(n) for integerToBinary method and O(n) for divideByTwo that runs inside the loop. Is there a way to achieve a better runtime? Thanks in advance!
Try this:
new BigDecimal("12345678901234567890123456789012345678901234567890").toString(2);
Edit:
For making a big-number class, you may want to have a look at my post about this a week ago. Ah, the question was by you, never mind.
The conversion between different number systems in principle is a repeated "division, remainder, multiply, add" operation. Let's look at an example:
We want to convert 123 from decimal to a base 3 number. What do we do?
Take the remainder modulo 3 - prepend this digit to the result.
Divide by 3.
If the number is bigger than 0, continue with this number at step 1
So it looks like this:
123 % 3 == 0. ==> The last digit is 0.
123 / 3 == 41.
41 % 3 == 2 ==> The second last digit is 2.
41 / 3 == 13
13 % 3 == 1 ==> The third digit is 1.
13 / 3 == 4
4 % 3 == 1 ==> The fourth digit is 1 again.
4 / 3 == 1
1 % 3 == 1 ==> The fifth digit is 1.
So, we have 11120 as the result.
The problem is that for this you need to have already some kind of division by 3 in decimal format, which is usually not the case if you don't implement your number in a decimal-based format (like I did in the answer to your last question linked above).
But it works for converting from your internal number format to any external format.
So, let's look at how we would do the inverse calculation, from 11120 (base 3) to its decimal equivalent. (Base 3 is here the placeholder for an arbitrary radix, Base 10 the placeholder for your internal radix.) In principle, this number can be written as this:
1 * 3^4 + 1 * 3^3 + 1*3^2 + 2*3^1 + 0*3^0
A better way (faster to calculate) is this:
((((1 * 3) + 1 )*3 + 1 )*3 + 2)*3 + 0
1
3
4
12
13
39
41
123
123
(This is known as Horner scheme, normally used for calculating values of polynomials.)
You can implement this in the number scheme you are implementing, if you know how to represent the input radix (and the digits) in your target system.
(I just added such a calculation to my DecimalBigInt class, but you may want to do the calculations directly in your internal data structure instead of creating a new object (or even two) of your BigNumber class for every decimal digit to be input.)
Among the simple methods there are two possible approaches (all numbers that appear here decimal)
work in decimal and divide by 2 in each step as you outlined in the question
work in binary and multiply by 10 in each step for example 123 = ((1 * 10) + 2) * 10 + 3
If you are working on a binary computer the approach 2 may be easier.
See for example this post for a more in-depth discussion of the topic.
In wikipedia, it is said:
For very large numbers, these simple methods are inefficient because
they perform a large number of multiplications or divisions where one
operand is very large. A simple divide-and-conquer algorithm is more
effective asymptotically: given a binary number, it is divided by
10^k, where k is chosen so that the quotient roughly equals the
remainder; then each of these pieces is converted to decimal and the
two are concatenated. Given a decimal number, it can be split into two
pieces of about the same size, each of which is converted to binary,
whereupon the first converted piece is multiplied by 10^k and added to
the second converted piece, where k is the number of decimal digits in
the second, least-significant piece before conversion.
I have tried, this method is faster than conventional one for numbers larger than 10,000 digits.
i'm getting back to software development and i was playing around with algorithms in java,and today i'm doing the algorithm the splits a number to a separate digits, I've found it here i wrote it in java ..it works but honestly i don't how ?? there is the code just i didn't understand a part of it :
public static void main(String[] args) {
Integer test = 0, i, N;
ArrayList array_one= new ArrayList<Integer>();
Scanner sc = new Scanner(System.in);
System.out.print("Write An Integer :");
test = sc.nextInt();
while (test > 0){
int mod = test % 10; // <= DON'T UNDERSTAND THE WORK OF THAT PART
// (i know it's the modulo of the entered value)
test = test / 10;
array_one.add(mod);
}
System.out.print(array_one);
}
i know it's a newbie question i'm just passionate about software engineering and algorithms just want to know how it exactly works and thks in advance.
test % 10; gives you the last (least significant) digit of the number, which is the remainder when dividing the number by 10.
test = test / 10 reduces the number by one digit (123456 becomes 12345), making the former 2nd least significant digit the new least significant digit. Therefore, in the next iteration, test % 10; would return the 2nd digit.
And so on...
test % 10; --> Always gives you the last digit.
test / 10; --> divides the existing number by 10.
while loop --> executes until test > 0
So, if your number is 234,
234%10 would be 4
234/10 would be 23.4 which will be converted to 23.
Apply 23 % 10 and 23/10 and so on..
By using %10 you'll get only the last digit.
/10 will give what is before your last digit.
And so you can construct your array.
124%10 --> 4
124/10 --> 12 % 10 --> 2
12 / 10 --> 1
The logic used here is to separate the units place first by dividing the number by 10 and getting the reminder value.
e.g x=153
"% " is the modulus operator that gives the remainder of the division
"/" is the division operator that gives only the quotient
then 153%10= 3 //this is the remainder that separates the first digit.
The number is then divided by 10 so as to get the quotient
i.e 153/10 =15 // Only the quotient
Progressing with the loop, now 15 is taken as the new original number and is again divided by 10 to get the remainder and hence the next digit.
i.e 15%10 =5 //next digit
15/10=1;
1%10=1 //digit
1/10=0 //The loop ends here
You can understand it by an example
Your number to divide it's digits is 345
If you divide it by 10 your remaining and first digit is 5
The question asks: Design and implement an application that first reads a list of 10 three-digit integers and then counts the number of appearances for each digit from 0 to 9.
Here is an example of 3 three-digit numbers
Input number [123, 456, 789]
Output:
Digit 0 has appeared 0 times
Digit 1 has appeared 1 times
Digit 2 has appeared 1 times
…
Digit 9 has appeared 1 times
I believe that I have figured out the correct formulas to computate the amount of times each number appears, but I am not sure how to create the array and begin searching through it. I think I need a while and a for loop, but I am not sure how to incorporate them. I am afraid however, that my current if statements will need to change once the loops are implemented. Am I going in the right direction here? Any help would be greatly appreciated!
double i1, i2, i3, i4, i5, i6, i7, i8, i9, i10;
int c0=0, c1=0, c2=0, c3=0, c4=0, c5=0, c6=0, c7=0, c8=0, c9=0;
Scanner scan = new Scanner(System.in);
System.out.println ("Enter 10 3-digit integers");
//Counts the 1st number
System.out.println ("Enter first 3-digit integer");
i1 = scan.nextDouble();
if (i1%10==0)
c0++;
if (i1%10==1)
c1++;
if (i1%10==2)
c2++;
if (i1%10==3)
c3++;
if (i1%10==4)
c4++;
if (i1%10==5)
c5++;
if (i1%10==6)
c6++;
if (i1%10==7)
c7++;
if (i1%10==8)
c8++;
if (i1%10==9)
c9++;
if ((i1%100>=0) & (i1%100<10))
c0++;
if ((i1%100>=10) & (i1%100<20))
c1++;
if ((i1%100>=20) & (i1%100<30))
c2++;
if ((i1%100>=30) & (i1%100<40))
c3++;
if ((i1%100>=40) & (i1%100<50))
c4++;
if ((i1%100>=50) & (i1%100<60))
c5++;
if ((i1%100>=60) & (i1%100<70))
c6++;
if ((i1%100>=70) & (i1%100<80))
c7++;
if ((i1%100>=80) & (i1%100<90))
c8++;
if ((i1%100>=90) & (i1%100<100))
c9++;
if((i1/1000>=.0) & (i1/1000<.1))
c0++;
if((i1/1000>=.1) & (i1/1000<.2))
c1++;
if((i1/1000>=.2) & (i1/1000<.3))
c2++;
if((i1/1000>=.3) & (i1/1000<.4))
c3++;
if((i1/1000>=.4) & (i1/1000<.5))
c4++;
if((i1/1000>=.5) & (i1/1000<.6))
c5++;
if((i1/1000>=.6) & (i1/1000<.7))
c6++;
if((i1/1000>=.7) & (i1/1000<.8))
c7++;
if((i1/1000>=.8) & (i1/1000<.9))
c8++;
if((i1/1000>=.9) & (i1/1000<1.00))
c9++;
Hints:
Get rid of all of the c<n> and i<n> declarations and all of the if tests. They don't help you solve the problem.
Make use of the fact that '0' + <n> == '<n>' where <n> is 0 .. 9.
Or use Character.digit(char, 10). Read the javadocs.
You don't use nextDouble() to read an integer. Read the javadocs.
More Hints:
Generalise the problem to 'count the distinct characters in a string'. Since you're reading the input as a string anyway, just forget that you're counting integers for the moment, and focus on counting char appearances within a string.
Think of a data structure that can contain a pair of (distinct char, count).
Iterate through the characters within a string, add the character to your data structure in point 2 if it doesn't exist with a default value of 0, then increment the count of the char you're currently looking at.
When showing the output of your program, iterate through the entries of your data structure, validate that the char is an integer (if validation is important), and return the count for that char.
I'm not sure if you have trouble with iteration or not, but here is how to loop through the characters of a string:
String s = "123 456 789";
for (int i = 0; i < s.length(); i++){
char c = s.charAt(i);
// process c
}
// or, if you know what 'smart loops' in Java are...
for(char c : s.toCharArray()) {
// process c
}
To confuse matters, here it is in... 'pseudocode' (edited based on comments) ;)
>>> s = "012 345 678 900"
>>> datastructure = {}
>>> for c in s:
... if c not in datastructure:
... datastructure[c] = 0
... datastructure[c] += 1
...
>>> for c in '0123456789':
... if c not in datastructure:
... datastructure[c] = 0
... print 'Digit %s appeared %d times' % (c, datastructure[c])
...
Digit 0 appeared 3 times
Digit 1 appeared 1 times
Digit 2 appeared 1 times
Digit 3 appeared 1 times
Digit 4 appeared 1 times
Digit 5 appeared 1 times
Digit 6 appeared 1 times
Digit 7 appeared 1 times
Digit 8 appeared 1 times
Digit 9 appeared 1 times
Your idea isn't that bad, you just obviously need some loops :)
1: loop to get numbers - you can't duplicate the same code 10x - write it once, in a loop.
2: loop to check digits - you can use your's ifs, or do it as Josh said
but before - you need data structure to store your data - occurs of digits. 10 variables is bad, BAD:), idea.
use array[2][10] or simply array[10] (where number of digits = index of array and value = occurs) or even better - HashMap<> - google it.
then inside loop you do:
for(int i = 0; i<10; i++){
if (myCurrentNumberToCheck %10 == i)
array[i] = array[i] + 1; // approach with simple array[10]
if ((myCurrentNumberToCheck %100 >= i*10) && (myCurrentNumberToCheck %100 < (i+1)*10 )) // needs to be tested
array[i] = array[i] + 1;
if ((myCurrentNumberToCheck %1000 >= i*100) && (myCurrentNumberToCheck %1000 < (i+1)*100 )) // needs to be tested
array[i] = array[i] + 1;
}
ahh and your inserted numbers should be in some structure too - try List numbers = new ArrayList<int>() here :) and iterate thou list, to take a look at next number.
so you will need to add numbers to List, and nextly - go thou that list and check them and here use that loop i wrote above
the problem with readInt() and readDouble() is that it ignores leading 0 and trailing 0 after the decimal i.e. 01.10 => 1.1
A much simpler approach is to just read every character.
int ch;
while((ch = System.in.read())>=0) {
// you have one character
}