public byte[] d
In this byte array, each byte represents a digits, where d[0] is the least significant digit, and a[d.length-1] is the most significant digit. For example, 543210 is stored as {0,1,2,3,4,5}. The most significant digit can't be a zero;
In the real implementation, this array should be private.
Constructor Detail: AdditionOnlyInt
public AdditionOnlyInt(java.lang.String a)
This is a constructor that construct an AdditionOnlyInt with value presented by the input string. For example, if input a = "00012340", this constructor will set the byte array to have value {0,4,3,2,1}. Note that the leading zeros in the input string should not be stored.
Parameters:a - is a string such as "00012340"
I do not know how to do this constructor does anyone?
I know its very wrong but I tried this
public AdditionOnlyInt(String number) {
int counter = number.length();
number.replace("0","");
data = new byte[number.length()];
int i = 0;
while(i<number.length()) {
data[i] = (byte)number.charAt(counter);
i++;
counter--;
}
}
and I do know converting to byte gives you different values.
You're in luck: only a handful of modifications need to be made to your program. You weren't entirely wrong. :)
First, these three statements are giving you fits:
int counter = number.length();
number.replace("0","");
data = new byte[number.length()];
You get a counter, which is the unbiased String (that is, with zeroes), which will undoubtedly be smaller than the String, without zeroes. You'd also be creating the array with the size of the unbiased list.
Well...it would be if your second statement did something. String is immutable, so anything that's done to modify it would only generate a new String, leaving the old one unmodified. That's fixable by this:
number = number.replace("0", "");
...but in reality, given your input set, it should be fixed by this:
number = String.valueOf(Integer.parseInt(number));
This way, you keep internal zeroes.
Now assuming that your byte[] is actually called data and not d, there's one little issue we have to fix: numbers in terms of a byte are quite large (that is, the character for '7' is 0x37, which is 55).
So we need to bias it. Whatever our byte number is, we need to subtract '0' from it; that is, we need to subtract 48 from it, to give us our correct value. I'll show you what that looks like in a moment.
Now, for your loop:
int i = 0;
while(i<number.length()) {
data[i] = (byte)number.charAt(counter);
i++;
counter--;
}
I'm not sold on the necessity of counter, so let's get rid of it. Now we'll use i from now on. Essentially, what this means is that we have to move charAt from the end of the String to the front of the String, placing the values into the array as such. What that (mostly) looks like is this:
data[i] = (byte) (number.charAt(number.length() - 1 - i);
Pay close attention here - we have to subtract 1 from the length right off the bat, since we don't have a place on the String that's exactly equal to its maximum length. We then subtract i from that, so we get the effect of moving backwards on the String.
That is, for a string of length 10 without zeroes, if we start at i = 0, we get the character at 10 - 1 - 0 = 9, or the last character.
Remember what I said about biasing the result of that, though? After you've got the data, be sure to subtract '0' from it.
data[i] = (byte) (number.charAt(number.length() - 1 - i) - '0';
And really, that's all there is to it. You mostly got it, except the iteration and sanitization was a bit wonky.
public AdditionOnlyInt(String input)
{
//remove trailing 0s
int relevStart = 0;
while(input.charAt(relevStart) == '0')
{
relevStart++;
}
String relevantTerms = input.substring(relevStart);
//flip the remaining chars
int length = relevantTerms.length();
data = new byte[length];
for(int iter = 0; iter < length; iter++)
{
data[iter] = (byte) (relevantTerms.charAt(length - iter - 1) - '0');
}
}
Hope this helps.
Step 1: Check whether its a number by using Integer value = Integer.valueOf(args);
Step 2: convert the Integer into a byte array by calling byte array[] = value.toString().getBytes();
Step 3: the byte array contains the value in forward fashion, So swapping all the values in the array will make the digit reverse as user requested.
for (int i = 0, j = array.length - 1; i < array.length / 2; i++, j--) {
byte temp = array[i];
array[i] = array[j];
array[j] = temp;
}
find the complete program below:
public class AdditionOnlyInt {
public static void main(String[] args) {
// TODO Auto-generated method stub
new AdditionOnlyInt("01010120");
}
public AdditionOnlyInt(String args) {
try {
Integer value = Integer.valueOf(args);
byte array[] = value.toString().getBytes();
for (int i = 0, j = array.length - 1; i < array.length / 2; i++, j--) {
byte temp = array[i];
array[i] = array[j];
array[j] = temp;
}
for (int i = 0; i < array.length; i++) {
System.out.print((char) array[i]);
}
} catch (Exception e) {
}
}
}
Related
So I was trying to build a solitaire encryption program, but I keep running into a problem when it comes to this method. The char array a represents the word the user inputs (converted it into an array to make it easier) and the char array b represents the alphabets so it has 25 indexes. What I am trying to do is match the alphabet to its number. It seemed simple enough but I am having a hard time as it keeps throwing an ArrayIndexOutOfBoundsException. I have tried to use for loops, nested for loops and other tests but it keeps throwing the exception or just outputs unexpected results such as [0, 0, 0, 0, 0]. I have debugged it and it seems like b[i] never equals a[j] so j will always be 0.
public static int[] converter(char[] a, char[] b){
int[] res = new int[a.length];
int i = 0;
int j = 0;
while(i < a.length){
if(b[i] == Character.toUpperCase(a[j])){ //Does not run through the first loop at all
res[j] = i + 1;
j = j + 1;
} else {
i = i + 1;
}
}
return res;
}
Please do not link the similar question. It does not answer my question.
The code below is a solution. We want the wordCharacterIndex to iterate through the word to see the place where a character is. The characterIndex iterates through the characters to compare with the word's character present at the wordCharacterIndex. After setting the result, we need to reset the characterIndex so that it goes back to the first character in the character array to compare with the other word characters, if we didn't, the following characters of the word would need to be at a higher character index, which is not what we want. Naming variables actual words is very important to better understand what you are trying to do within your code. You were comparing i < a.length while you were iterating through b[i] which made it possible to go larger than b's bounds and therefore cause an ArrayIndexOutOfBoundsException. I hope this helps you better understand.
public static int[] converter(char[] word, char[] characters){
int[] result = new int[word.length];
int characterIndex = 0;
int wordCharacterIndex = 0;
while(wordCharacterIndex < word.length){
if(characters[characterIndex] == Character.toUpperCase(word[wordCharacterIndex])){
result[wordCharacterIndex] = characterIndex + 1;
wordCharacterIndex++;
characterIndex = 0;
} else {
characterIndex++;
}
}
return result;
}
I'm currently working on a small challenge, trying to figure out how an unnamed encryption algorithm works. The original algorithm looks like this:
public final String a(byte[] original)
{
this.a = original.length;
byte[] solution = new byte[8];
int i = 0;
int base = 13;
for (int si = 0; si < 8; si++)
{
for (int oi = 0; oi < a; oi++)
{
byte current = original[oi];
solution[i] = ((byte)(solution[i] + (current ^ base)));
base = (base ^ i) + solution[i];
i = (i + 1) % 8;
}
}
char[] result = new char[8];
for (int n = 0; n < 8; n++) {
result[n] = ((char)((solution[n] & 0x3F) + 48));
}
return String.valueOf(result);
}
So every string that gets passed to this function as a byte[] array will be encoded into a 8-char somewhat cryptic text. I've found out other things about this:
The encoded characters in the char[] result always have literals with values between 48 and 111 (0x3F + 48).
When decoding, the first step would be subtracting 48 and then undo the & operation. Since 0x3F equals the binary representation 111111, the value of the original byte is one of 4 possibilities:
00xxxxxx: the missing 2 bits were both zero.
01xxxxxx: the lower addressed bit of both was one.
10xxxxxx: the higher addressed bit of both was one.
11xxxxxx: both of them were one.
Meaning, it could be one of four characters. I initially thought about reversing the algorithm, but I'm asking you if this is even possible for this kind of algorithm. I tried it and came this far:
public static String b(String encrypted) {
byte[][] matrix = new byte[4][20];
byte[] word = encrypted.getBytes();
for(int i = 0; i < 4; i++) {
for(int j = 0; j < word.length; j++) {
byte tmp = (byte)(word[i] - 48);
matrix[i][j] = (byte)(tmp + i);
}
}
}
I currently subtract 48 and insert all 4 possibilities into a 2D-array. But im stuck solving the nested for loop, especially the variables i and base are hard to find out. The only information I have is the encrypted word and the fact that the original word was 20 literals long at MAX (Hence the [4][20] dimensions).
The encryption doesn't look familiar to me, which leaves me no options to look for the name of this algorithm.
If it is possible to reverse this algorithm, what would my next step be?
No, that obviously can't be reversible in the general case.
There are effectively 40 bits of information in the output (eight bytes, at 5 bits each -- & 0x1F limits each one to five bits). This means that there are only 240 possible outputs; there are far more possible inputs than that.
If there are some constraints on the input -- for instance, if its length is known to be short -- it might be possible to make some inferences about that. However, you haven't stated any constraints, so…
I created a method for finding the most common character in a string:
public static char getMax(String s) {
char maxappearchar = ' ';
int counter = 0;
int[] charcnt = new int[Character.MAX_VALUE + 1];
for (int i = 0 ; i < s.length() ; i++)
{
char ch = s.charAt(i);
// increment this character's cnt and compare it to our max.
charcnt[ch]++ ;
if (charcnt[ch] >= counter)
{
counter = charcnt[ch];
maxappearchar = ch;
}
}
System.out.println("the max char is " +maxappearchar + " and displayed " +counter+ " times");
return maxappearchar;
}
I am asking about different solutions for it:
solution 1 - Fastest code (is that my attached code?)
solution 2 - Most effective in terms of memory, reduced use of arrays and variables
I created my method using HashMap - is that more Suitable for solution 2? If so why? And what are the pros/cons?
Is the attached code is suitable for o Technique (o^ , o logn ... )? If so why?
The fastest way to do this will be to count occurrences of every character, then take the max value in the count array. If your string is long, you'll gain a decent speedup from not tracking the current max while looping over characters in the String.
See How to count frequency of characters in a string? for many other ideas about how to count frequencies.
If your Strings are mostly ASCII, a branch in the count loop to choose between an array for the low 128 char values, or a HashMap for the rest, should be worth it. The branch will predict well if your strings don't have non-ASCII characters. If there's a lot of alternating between ascii and non-ascii, the branch might hurt a bit, compared to using HashMap for everything.
public static char getMax(String s) {
char maxappearchar = ' ';
int counter = 0;
int[] ascii_count = new int[128]; // fast path for ASCII
HashMap<Character,Integer> nonascii_count = new HashMap<Character,Integer>();
for (int i = 0 ; i < s.length() ; i++)
{
char ch = s.charAt(i); // This does appear to be the recommended way to iterate over a String
// alternatively, iterate over 32bit Unicode codepoints, not UTF-16 chars, if that matters.
if (ch < 128) {
ascii_count[ch]++;
} else {
// some code to set or increment the nonascii_count[ch];
}
}
// loop over ascii_count and find the highest element
// loop over the keys in nonascii_count, and see if any of them are even higher.
return maxappearchar;
}
I didn't flesh out the code, since I don't do a lot of Java, so IDK if there's a container than can do the insert-1-or-increment operation more efficiently than a HashMap get and put pair. https://stackoverflow.com/a/6712620/224132 suggests Guava MultiSet<Character>, which looks good.
This may do better than your array of 2^16 ints. However, if you only ever touch the low 128 elements of this array, then most of the memory may never be touched. Allocated but untouched memory doesn't really hurt, or use up RAM / swap.
However, looping over all 65536 entries at the end means at least reading it, so the OS would have to soft pagefault it in and wire it up. And it will pollute caches. So actually, updating the max on every character might be a better choice. Microbenchmarks might show that iterating over the String, then looping over charcnt[Character.MAX_VALUE] wins, but that wouldn't account for the cache / TLB pollution of touching that much not-really-needed memory.
It is a fast algorithm using much space.
It does not cover full Unicode, there are code points (Unicode characters, ints) that need two chars.
Small optimizations still possible:
Making extra versions with byte[] and short[], depending on s.length().
Keeping the length() in a variable
for (int i = 0, n = s.length(); i < n; i++)
And yes a HashMap probably is the most "sensible" solution.
Now with java 8, you might turn to parallelism: using multiple cores. Not worth the effort.
int mostFrequentCodePoint = s.codePoints()
...
For frequency analysis in natural language, it may suffice to limit the string's length to 1000 or so.
public class HelloWorld {
public static void main(String[] args) {
String word = "Ferrari";
String mostUsedChar = "";
int count = 0;
String[] array = word.split("");
for (int i = 0; i < array.length; i++) {
int tempCount = 0;
for (int j = 0; j < array.length; j++)
{
if (array[i].equals(array[j])) {
tempCount++;
}
if (tempCount > count) {
count = tempCount;
mostUsedChar = array[i];
}
}
}
System.out.println(count + " Most Used Char: " + mostUsedChar);
}
}
Using the solution above returning a SimpleEntry<Character,Integer> (full implementation) for ASCII:
public static Map.Entry getMostCommonChar(String phrase) {
if (phrase == null || phrase.isEmpty()) {
throw new IllegalArgumentException("input phrase must have non-empty value.");
}
char maxchar = ' ';
int counter = 0;
int[] ascii_count = new int[Character.MAX_VALUE]; // fast path for ASCII
for (int i = 0; i < phrase.length(); i++) {
char ch = phrase.charAt(i); // This does appear to be the recommended way to iterate over a String
if (ascii_count[ch]++ >= counter) {
counter = ascii_count[ch];
maxchar = ch;
}
}
Map.Entry<Character,Integer> e = new AbstractMap.SimpleEntry<>(maxchar,counter);
System.out.println(e.getKey());
System.out.println(e.getValue());
return e;
}
I'm trying to create a code that writes an array backwards and can only use an array, character, and an integer. So far I have this, but it isn't doing anything. I'm a beginner at java.
import javax.swing.JOptionPane;
public class TestingArraysUsingOneArray
{
public static void main(String args[])
{
{
String str = JOptionPane.showInputDialog("Enter any text that you want to reverse.");
char[] charArray = str.toCharArray();
char current;
int a = 0;
for (int i = 0; i>=str.length()%2; i++) {
current = str.charAt(a);
charArray[a] = str.charAt(str.length()-a);
charArray[str.length()-a] = current;
a++;
}
System.out.println(charArray);
}
}
}
The output I'm getting is hello when I enter in hello. What do I need to change to get this program to work?
Your don't need half the code. I would try to make it as simple as possible. Try this
String str = ...
for(int i = str.length() - 1; i >= 0; i--)
System.out.print(str.chatAt(i));
System.out.println();
If the assignment says you have to reverse an array of chars you can do this.
String str = ...
char[] chars = str.toCharArray();
for(int i = 0; i < chars.length/2; i++) {
char ch = chars[i];
chars[i] = chars[chars.length - i - 1];
chars[chars.length - i - 1] = ch;
}
System.out.println(new String(chars));
As you can see this is needlessly complicated, so you would not do this. Another way you can do this if you don't want to use a loop is
String str = ...
System.out.println(new StringBuilder(str).reverse());
Well, for one thing, I think you want i<str.length()/2 - this will give you half the length. If you say i>=str.length()%2, you're getting the remainder when its length is divided by 2 - which is always either 1 or 0, and the loop continues as long as i is more than either 1 or 0. This should result in an infinite loop. Also, you don't need the variable a, as it is always equivalent to i. This, however, results in the string index being out of bounds sometimes, but I'll let you figure out how to solve that.
Your for loop is never entering because it should be i < str.length(), because at the moment when i is 0, the current check will immediately fail.
With that condition set, you need to change the two instances of str.length()-a to str.length()-a-1, because str.length-a when a is 0 will cause an StringIndexOutOfBoundException because the maximum index you can access is str.length-1.
Those are just corrections to the existing code. There's a better, more concise way of reversing the string suggested in another answer, which is the one you should accept.
What you want to do is replace the first character with the last and so on..
char[] charArray = str.toCharArray();
char current;
for (int i = 0; i < charArray.length / 2; i++) {
current = charArray[i];
charArray[i] = charArray[charArray.length - i - 1];
charArray[charArray.length - i - 1] = current;
}
The a int is completely redundant, and it would be a second int in your code - don't forget the variable in the for loop.
Suppose I have a string of 123456789. I would like to split this string and each number goes in a different slot in the array. I can't use the split() method because there is nothing to split on. How would I accomplish this in Java.
int x=123456789;
char[] array = x.toString().toCharArray();
int intarray[] = new int[array.length];
for (int i = 0; i < array.length; i++) {
intarray[i] = Integer.parseInt(array[i]);
}
And after this you intarray will be array of your numbers.
If your integer can be negative too, you must take it's absolute value and make same operations, and after that multiple first array value by -1. But I guess, it's not needed.
EDIT:
I think, I don't understand your question properly. If you want to split only string, you must use this lines only. I wrote about integers,which might be helpful too.
string x="123456789";
char[] array = x.toCharArray();
If you're only dealing with non-negative integers, the toCharArray() method should be suitable for you. It gives you the string as an array.
The String class has a neat method for doing this, toCharArray().
You can use the following to avoid creating Strings.
long x = x;
ByteBuffer bb = ByteBuffer.allocate(18);
if (x == 0) {
bb.put((byte) 0);
} else {
while (x > 0) {
bb.put((byte) (x % 10));
x /= 10;
}
}
int len = bb.position();
byte[] digits = new byte[len];
for (int i = 0; i < len; i++)
digits[i] = bb.get(len - i - 1);
is it compelsory that the data will be of single digit ?If the data may come in multiple digits then it will not be possible to identify whether the numeric value is of single digit of multiple digit ?
e.g. if it is 12(twelve) then if all string is 512 then how will you identify whether to represent 512 as 5,1,2 or 5,12 ?
if it is fix that the numbers will be in single digits and non negetives then toCharArray() of String class will work for you