Integer manipulation in Java - java

I have an assignment to be done in college, a piece asks for the instructions below to be done. Please don't give away the answer, simply leading me in the right direction would be awesome.
All the data is transmitted as four-digit integers. You program should read a four-digit integer entered by the user and encrypt it as follows:
- Replace each digit with the result of adding 7 to the digit and getting the remainder after dividing the new value by 10. Then,
- Swap the first digit with the third, and the second with the fourth.
i can do everything but swapping the digits at the end of the instructions.
All help greatly appreciated,
thanks guys!

First break down the program into logical steps:
Get input from the user
Check that the input is a 4-digit number
Split up the number into individual digits
Perform the remainder calculation on each digit
Reassemble the 4-digit number, swapping digits as required
Print the output.
I imagine you can do at least some of that, so let us know what you've done so far.

First of all, you need to get every digit in the number and store in separate variables (in an array or a list).
Let's say
number = 1763
Your array would look like this:
list[0] = 3
list[1] = 6
list[2] = 7
list[3] = 1
Then for each member of the list, do this:
list[i] = (list[i] + 7) % 10;
Then swap the elements in the list as directed. Write a swap function so that you can reuse it.
swap(int[] array, int i, int j) {
// Check for array boundary violation
// Swap the elements of the array identified by indexes i and j
int tmp = array[i]; array[i] = array[j]; array[j] = tmp;
}
Then construct your number out of the array. Note that array indexes will be the power of 10 when summing up the figures.
This solution will easily scale to n-digit integers.

The first step you will want to do is to split the 4 digit integer into its individual digits. To do this, you need to understand base 10 representation of numbers.
Once you understand how to split the number into the individual digits, the rest of the operations should be fairly easy to do.

Related

Getting exponents in a method without using Math.pow()

This was the problem I was given:
Create method lastDigit that is passed two positive integers. The first integer is the base and the second integer is the exponent. lastDigit will return the last digit of base^exponent. You need to think before you write your code. Hint: You do not need to actually find the product of base^exponent.
Then I need to use the method to find answer the questions below:
1) What is the last digit of 3^400?
2) What is the last digit of (3^0)(3^1)(3^2)(3^3)…(3^10)?
3) What is the last digit of the product of (3^0)(3^1)(3^2)…..(3^400)?
Here's the code that I wrote:
public static int lastDigit(int m, int n){
int p=1;
for(int i=1; i<=n; i++)
p=p*m;
return p%10;
}
However when I was trying to find the answers to the questions, I keep getting -1 for both the first and third questions, and 1 for the second question. Is there something wrong with the code, or how can I get the right answer?
You or a program you wrote may be suffering from Integer Overflow.
This is caused by chronic limitation of the int type.
Symptoms include
Negative integers that are really supposed to be positive
Small numbers that are supposed to be big
This condition can be controlled by ensuring that your int values don't exceed 2 billion.
If symptoms persist, see a debugger, or print out intermediate values.
*side effects may include frustration, throwing your computer out of a window, and/or deleting important system files.
But in all reality, let's say that you have a base of seven.
7=7
7*7=49
49*7=343
The last digit is 3.
However, if you, only take the last digit in between operations,
7*7 =49 -> 9
9*7 =63
The last digit is still three.
Doing this keeps the number well below the int limit.
This is actually what the p=(p*m)%10; solution is:
p= (p*m) %10
multiply the previous digit by the exponent take the last digit
The int variable is overflowing. Try changing p=p*m to p=(p*m)%10.

how to find the most frequent character in a big string using java?

i'm working on an assignment that i have to find the most four frequent characters in a string.
i write this so far.
import java.util.Scanner;
public class FindTheMostOccur
{
public static void main (String[] args)
{
String input;
String example = "how to find the most frequent character in a big string using java?";
String[] array = new String[example.length()];
for (int i = 97; i < 123; i++)
{
int mostFrequent =0;
for( int j = 0; j < example.length(); j++)
{
if(example.charAt(j) == i)
{
++mostFrequent;
}
}
System.out.println( (char)i + " is showing " + mostFrequent+ " times ");
}
}
}
Here is the output for this example.
a is showing 5 times
b is showing 1 times
c is showing 2 times
d is showing 1 times
e is showing 4 times
f is showing 2 times
g is showing 3 times
h is showing 3 times
i is showing 5 times
j is showing 1 times
k is showing 0 times
l is showing 0 times
m is showing 1 times
n is showing 5 times
o is showing 3 times
p is showing 0 times
q is showing 1 times
r is showing 4 times
s is showing 3 times
t is showing 6 times
u is showing 2 times
v is showing 1 times
w is showing 1 times
x is showing 0 times
y is showing 0 times
in this examle : t, a,i,n
I DON"T NEED SOMEONE TO COMPLETE THE PROGRAM FOR ME, however i need some ideas how to find the most four frequent character in this example.
The simplest algorithm I can think of off hand is that instead of doing multiple passes do a single pass.
Create a HashMap mapping from character to count.
Each time you find a character if it is not in the map, add it with value 1. If it is in the map increment the count.
At the end of the loop your HashMap now contains the count for every character in the String.
Take the EntrySet from the HashMap and dump it into a new ArrayList.
Sort the ArrayList with a custom comparator that uses entry.getValue() to compare by.
The first (or last depending on the sort direction) values in the ArrayList will be the ones you want.
How about this?
int count[] = new int[1000];// all with zero
Then for each character from the string, do count[]++ like this way
count['c']++;
count['A']++;
At the end, find out which index holds the maximum value. Then just print the ascii of that index.
Ok, here're some ideas:
To find the 4 most frequent characters, you must first know the frequency for all the characters. So, you would need to store the frequency somewhere. Currently, you are just printing the frequency of each character. You can't compare that way. So, you need a data structure.
Here we are talking about mapping from a chararacter to its count. Possibly you need a hash table. Look out for the hash table implementation in Java. You will find HashMap, LinkedHashMap, TreeMap.
Since you want the 4 most frequent characters, you need to order the characters by their frequency. Find out what kind of map stores the elements in sorted order. Note: You need to sort the map by values, not keys. And sort it in descending order, which is obvious.
Using Array:
There is another approach you can follow. You can create an array of size 26, assuming you only want to count frequency of alphabetic characters.
int[] frequency = new int[26];
Each index of that array correspond to the frequency of a single character. Iterate over the string, and increment the index corresponding to the current character by 1.
You can do character to index mapping like this:
int index = ch - 'a';
So, for character 'a', the index will be 0, for character 'b', index will be 1, so on. You might also want to take care of case sensitivity.
Problem with the array approach is, once you sort the array to get 4 most frequent character, you've lost the character to index mapping. So, you would need to have some way to sort the indices along with the frequency at those indices. Yes you're right. You need another array here.
But, will having 2 arrays make your problem easy? No. Because it's difficult to sort 2 arrays in synchronization. So what to do? You can create a class storing index and character. Maintain an array of that class reference, of size 26. Then find your way out to port the array approach to this array.
What data structures are you allowed to use?
I'm thinking that you can use a priority queue and increment the priority of the node containing the character that is being repeated. And when you are done, the first index would contain the node with the most repeated character
I got another idea that you can do it using an array only.
Well you have 26 letters in the Alphabet. The ASCII code of the lowercase letters range from 97 to 122(you can make every letter a lower case using .lowercase() or something similar).
So for each character, get its ASCII code, do the ASCII code -97 and increment it.
Simple,and only need an array.

Representing large numbers using linked lists and performing operations

I need to store two extremely large numbers (Strings, since they won't fit in int) in two linked lists, add them and then display the result (again, a String).
I can store the numbers directly into the list.
312312 can be stored as 2->1->3->2->1->3 (actual number will be extremely long)
111119 can be stored as 9->1->1->1->1->1
Then I can add them
11->2->4->3->2->4
Normally I could do 11*10^0 + 2*10^1 +...+ 4*10^5 and get 423431 but all those operations (multiplication, addition and exponentiation) would again be integer operations and since the actual numbers are going to be extremely big, int or long won't support the operations. The final result has to be a string.
So I need a way to convert 11->2->4->3->2->4 into 423431 without using int. Also, I cannot use BigInteger. Can anyone help me?
Well, first thing you need to do is implement carry.
For each digit (that is >= 10), you need to increase the next digit by that digit /10 and set that digit to that digit %10.
So 11->2->... becomes 1->3->....
Then to actually produce the string.
For the most performant option, I suggest StringBuilder.
Just append each digit in the linked-list, then just reverse().toString() (since you started with the smallest number).
Think about how you would do it by hand on paper. If the sum of a pair digits is greater than 9 you write down a carry digit of 1, which you add into the sum of the next pair of digits.
In a computer program you can use a local variable for that: add digits from first and last numbers and the carry from earlier, if sum is greater than.. set carry to 1, else set carry to 0, move on to the next pair...

Creating java array to convert numeric score to alphabetic grade

novice java programmer, new to arrays, working on an assignment of the following prompt:
Write a program that will plot the grade distribution of scores of a test. The scores are inputted one at a time and the loop will break when a score of 0 (zero) is entered. The output will print a * for each score in the letter grade and will place the letter grades on the horizontal axis below the graph.
My main issue is in the creation of an array that enables me to sum the number of scores in each grade (A, B, C...). I am prohibited from the use of if or switch statements in this conversion. I'm wondering where to start in the creation of this array. Thanks!
Does it have to be an array? If not, a Map is a good choice for this type of scenario. The keys of the map are the various grades (A, B, C, etc) and the value of each key is an integer (or long) to hold the number of grades for that key. So, the basic logic is to get the counter from the map for the grade (i.e. key), increment it and put it back into the map.
If you don't mind using external libraries, then Guava's Multiset is an even better fit.
EDIT: OK so you need to use an array, but one challenge (if I read your post correctly) is that you can't use if or switch statements (presumably to access the array). One possible way around this is to assign 'A' to index 0, 'B' to index 1, etc. Then you can use the following notation for array indexing:
char gradeAsChar = ...; //I'll leave this to you to get the grade as an (uppercase) char
gradesArray[gradeAsChar - 'A'] = gradesArray[gradeAsChar - 'A'] + 1;
'A' - 'A' is 0, 'B' - 'A' is 1, etc. The above, of course, is ripe for index out of bounds issues if the character is unexpected so you'll need some error handling there.
Of course, if you don't care about memory efficiency (which you always should while coding!), you can make a new array like so:
int[] grades = new int[101];
Then whenever a user enters an input, you can do something like:
int grade = input.nextInt();
grades[grade] = grades[grade] + 1;
You can figure out the number of grades that equal A by running something like:
int A = 0;
for (int i = 91; i < 101; i++){
A += grades[i];
}
That's what I thought of when you said you weren't allowed to use if or switch statements. Let me know if it helped. Again, terribly inefficient, but at least you keep track of all the scores you have. That's a plus.
This should be a rough runtime of O(n), but could be better I think.
Good luck!
EDIT: You can do a more efficient version of the method above by using the concept of integer division. What is integer division you may ask, it's when you divide two integers, say 10/3 and the answer might be 3.333 but java discards the fractional parts so that the answer is 3.
Therefore, if you divide by 10, you can use the result to get which scores are A and so forth. For example: 92/10 = 9, 97/10 = 9, 83/10 = 8, etc. The caveat is that the score is from 91-100 for A so you have to subtract 1 before applying this concept.
This should reduce the array from 101 elements to 10 since you are only keeping track of the number in the tens digit, which is more important anyways. You may be able to further optimize this but again, this isn't my homework so I don't want to spend too much time on it. I thought of this when I woke up :).
Hope this gave you some food for thought!

Find longest series of ones in a binary digit array

How would I find the longest series of ones in this array of binary digits - 100011101100111110011100
In this case the answer should be = 11111
I was thinking of looping through the array and checking every digit, if the digit is a one then add it to a new String, if its a zero re-start creating a new String but save the previously created String. When done check the length of every String to see which is the longest. I'm sure there is a simpler solution ?
Your algorithm is good, but you do not need to save all the temporary strings - they are all "ones" anyway.
You should simply have two variables "bestStartPosition" and "bestLength". After you find a sequence of "ones" - you compare the length of this sequence with saved "bestLength", and overwrite both variables with new position and length.
After you scanned all array - you will have the position of the longest sequence (in case you need it) and a length (by which you can generate a string of "ones").
Java 8 update with O(n) time complexity (and only 1 line):
int maxLength = Arrays.stream(bitStr.split("0+"))
.mapToInt(String::length)
.max().orElse(0);
See live demo.
This also automatically handles blank input, returning 0 in that case.
Java 7 compact solution, but O(n log n) time complexity:
Let the java API do all the work for you in just 3 lines:
String bits = "100011101100111110011100";
LinkedList<String> list = new LinkedList<String>(Arrays.asList(bits.split("0+")));
Collections.sort(list);
int maxLength = list.getLast().length(); // 5 for the example given
How this works:
bits.split("0+") breaks up the input into a String[] with each continuous chain of 1's (separated by all zeros - the regex for that is 0+) becoming an element of the array
Arrays.asList() turns the String[] into a List<String>
Create and populate a new LinkedList from the list just created
Use collections to sort the list. The longest chain of 1's will sort last
Get the length of the last element (the longest) in the list. That is why LinkedList was chosen - it has a getLast() method, which I thought was a nice convenience
For those who think this is "too heavy", with the sample input given it took less than 1ms to execute on my MacBook Pro. Unless your input String is gigabytes long, this code will execute very quickly.
EDITED
Suggested by Max, using Arrays.sort() is very similar and executes in half the time, but still requires 3 lines:
String[] split = bits.split("0+");
Arrays.sort(split);
int maxLength = split[split.length - 1].length();
Here is some pseudocode that should do what you want:
count = 0
longestCount = 0
foreach digit in binaryDigitArray:
if (digit == 1) count++
else:
longestCount = max(count, maxCount)
count = 0
longestCount = max(count, maxCount)
Easier would be to extract all sequences of 1s, sort them by length and pick the first one. However, depending on the language used it would probably be only a short version of my suggestion.
Got some preview code for php only, maybe your can rewrite to your language.
Which will say what the max length is of the 1's:
$match = preg_split("/0+/", "100011101100111110011100", -1, PREG_SPLIT_NO_EMPTY);
echo max(array_map('strlen', $match));
Result:
5

Categories