Related
I'm trying to search and reveal unknown characters in a string. Both strings are of length 12.
Example:
String s1 = "1x11222xx333";
String s2 = "111122223333"
The program should check for all unknowns in s1 represented by x|X and get the relevant chars in s2 and replace the x|X by the relevant char.
So far my code has replaced only the first x|X with the relevant char from s2 but printed duplicates for the rest of the unknowns with the char for the first x|X.
Here is my code:
String VoucherNumber = "1111x22xx333";
String VoucherRecord = "111122223333";
String testVoucher = null;
char x = 'x'|'X';
System.out.println(VoucherNumber); // including unknowns
//find x|X in the string VoucherNumber
for(int i = 0; i < VoucherNumber.length(); i++){
if (VoucherNumber.charAt(i) == x){
testVoucher = VoucherNumber.replace(VoucherNumber.charAt(i), VoucherRecord.charAt(i));
}
}
System.out.println(testVoucher); //after replacing unknowns
}
}
I am always a fan of using StringBuilders, so here's a solution using that:
private static String replaceUnknownChars(String strWithUnknownChars, String fullStr) {
StringBuilder sb = new StringBuilder(strWithUnknownChars);
while ((int index = Math.max(sb.toString().indexOf('x'), sb.toString().indexOf('X'))) != -1) {
sb.setCharAt(index, fullStr.charAt(index));
}
return sb.toString();
}
It's quite straightforward. You create a new string builder. While a x or X can still be found in the string builder (indexOf('X') != -1), get the index and setCharAt.
Your are using String.replace(char, char) the wrong way, the doc says
Returns a new string resulting from replacing all occurrences of oldChar in this string with newChar.
So you if you have more than one character, this will replace every one with the same value.
You need to "change" only the character at a specific spot, for this, the easiest is to use the char array that you can get with String.toCharArray, from this, this is you can use the same logic.
Of course, you can use String.indexOf to find the index of a specific character
Note : char c = 'x'|'X'; will not give you the expected result. This will do a binary operation giving a value that is not the one you want.
The OR will return 1 if one of the bit is 1.
0111 1000 (x)
0101 1000 (X)
OR
0111 1000 (x)
But the result will be an integer (every numeric operation return at minimum an integer, you can find more information about that)
You have two solution here, you either use two variable (or an array) or if you can, you use String.toLowerCase an use only char c = 'x'
I want to get a hexadecimal value from four boolean variables something like this example:
boolean[] m = {true, false, true, true};
I want to get a String or char that hold B which means 1011 in binary.
PS: I am working on an Android app.
You can use below code to get your binary string, integer value and hexDecimal value.
boolean[] m = {true,false,true,true};
String binaryStr = "";
for (boolean bit : m) {
binaryStr = binaryStr + ((bit) ? "1" : "0" );
}
int decimal = Integer.parseInt(binaryStr , 2);
String hexStr = Integer.toString(decimal , 16);
In above code, binaryStr is your Binary String i.e. 1011 and its equivalent decimal and hexa decimal value are decimal and hexStr
boolean[] booleanArray = new boolean[] { true, false, false, true };
String binaryString = Arrays.toString(booleanArray).replace("true", "1").replace("false", "0");
and just convert that binaryString to hexadecimalvalue
While the above answers do work, they have their limitations. The first limit being a cap at 32 booleans because of the 32 bit integer limit. But the above code also uses built-in methods, they don't allow a beginner to grasp what is really going on.
If you just want to get the job done, use something from above. It'll probably be more efficient. I'm just posting this solution because I feel it will allow someone who wants to grasp the actual concept do so better.
(Hopefully the comments make a little sense)
public static String booleanArrayToHex1(boolean[] arr){
if(!(arr.length%4==0)){arr=makeMultOf4(arr);} //If you are using arrays not in multiples of four, you can put a method here to add the correct number of zeros to he front.
//Remove the above line if your array will always have a length that is a multiple of 4
byte[] hexValues=new byte[arr.length/4];
//The array above is where the decimal hex values are stored, it is byte because the range we need is 0-16, bytes are the closest to that with the range of 0-255
int hexCounter=arr.length/4-1; //counts what hex number you are calculating
/* The below loop calculates chunks of 4 bianary numbers to it's hex value
* this works because 16 is a power of 2
* so if we simpily squish those numbers together it will be the same as finding the accual integer value of the whole thing
* This can go to higher numbers because we do not have the 32 bit integer limit
* it runs in reverse because the lowest value is on the right of the array (the ones place is on the right)
*/
for(int i=arr.length-1;i>=0;i--){
if(arr[i]){
int place=1; //will count the value of a bianary number in terms of its place
for(int j=3;j>i%4;j--)
//loop multiplies the bianary number by 2 j times, j being what place it's in (two's, four's, eight's). This gives the correct value for the number within the chunk.
//This is why the array needs to be a multiple of 4
place*=2;
hexValues[hexCounter]+=place; //this will add that place value to the current chunk, only if this place in the boolean array is true (because of the above if - statement)
}
if(i%4==0)//moves the chunk over one every 4 binary values
hexCounter--;
}
//Everything below simpily takes the array of decimal hex values, and converts to a alpha-numeric string (array to normal hex numbers)
String ret="";
for(byte b:hexValues)
switch(b){
case 10:
ret=ret+"A";
break;
case 11:
ret=ret+"B";
break;
case 12:
ret=ret+"C";
break;
case 13:
ret=ret+"D";
break;
case 14:
ret=ret+"E";
break;
case 15:
ret=ret+"F";
break;
default:
ret=ret+b;
break;
}
return ret;
}
If your array length is not a multiple of 4, to make this work you will need to make the array a multiple of 4. I have some code below that will do that. It's not commented, and probably not that efficient, but it works.
public static boolean[] makeMultOf4(boolean[] arr){
if(arr.length%4==0){return arr;}
boolean[] array=new boolean[arr.length+(arr.length%4==1?3:arr.length%4==2?2:1)];
for(int i=0;i<array.length;i++){
try{
array[i]=arr[i-(arr.length%4==1?3:arr.length%4==2?2:1)];
}catch(Exception e){
array[i]=false;
}
}
return array;
}
You can use this logic :
String x = "";
for(int i = 0 ; i < m.length ; i++){
if(m[i])
x += "1";
else
x += "0";
}
Log.i("values = ",x);
For each boolean value append to binary string 1 if true 0 otherwise, then using Integer.parseInt() convert binary string to Integer instance, finally convet integer to hex string using Integer.toHexString() method
#org.junit.Test
public void test() throws Exception{
boolean[] m = {true, false, true, true};
String binary = "";
for(boolean b : m) binary += b ? 1 : 0;
String hex = Integer.toHexString(Integer.parseInt(binary, 2));
System.out.println(hex);
}
Java question,
Say I have a number such as 0000102 and the 0s are important, as in they need to be there.
How can I save this information in an int(or some other way that would allow me to increment it)
For example, after checking the number 0000102 it would then add one to it and check for 0000103
When I try saving it as in int it just reverts to 102 and gets rid of the 0's, and therefore doesn't match as I search through a database since it is no longer the same. Does anyone know of a way I can do this without it removing the 0's. Thanks
EDIT:
My final solution for addition with leading zeros was this function, it takes a string with leading 0's adds one to it, then returns the string
String nextNum(String s){
int number =0;
String newNum ="";
int len = s.length();
int newLength =0;
for(int i =0; i < s.length()-1; i++){
if (s.charAt(i) == '0')
newNum+="0";
else
break;
}
number = Integer.parseInt(s);
number++;
newNum += String.valueOf(number);
newLength = newNum.length();
if(newLength == len)
return newNum;
else
return newNum.substring(1); //incase number was 000099 it doesnt go to 0000100 it goes to 000100 instead
}
You can use string formatting by combining printf with "%0d" as follows:
String num = "000123";
Integer n = Integer.parseInt(num);
n++;
int len = num.length();
System.out.printf("%0" + len + "d", n); // 000124
// and if you want to store the result
// back into a string:
String res = String.format("%0" + len + "d", n);
System.out.println(res); // 000124
You would store the value as an int (without zeroes) but could convert it into a String with leading zeroes when you want to print or display it. Here is an example conversion method.
public String addZeroes(int value, int desiredLength) {
String valueString = value + "";
int valueLength = valueString.length();
for (int i = 0; i < desiredLength - valueLength; i++) {
valueString = "0" + valueString;
}
return valueString;
}
The number itself is separate from the representation of the number. The number associated with what we usually call "ten" is always the quantity that counts these: ||||||||||, but it has many possible string representations: "10", "0000010", "0x0a", "1010(2)"... (not all of these are valid Java representations, just various representations that humans are using)
Your number will always be stored in the computer in such a way that the quantity can be (mostly) accurately handled. The string representation is normally not stored; it is calculated each time. For example, when you do System.out.println(102), it is actually handled as System.out.println(Integer.toString(102, 10)).
Between 102 and "0000102", figure which one you want to store and which one you want to display, and convert appropriately when you need the other one.
You'll need to use a String.
The decimal numbers 000102 and 0102 and 102 (and for that matter, the hex number 0x66) are all the same integer value, there is no way to distinguish between them once you store them as an int.
If you want to preserve a specific character representation of your integer, then you need a string.
To increment the String you'll need to parse it to an Integer, and then reformat it.
String increment(String s) {
int n = Integer.parseInt(s, 10)
return ("%0" + s.length() + "d").format(n+1);
}
You say you need to keep track of the leading zeroes, but that's separate from the number itself. I would keep the number itself as an int, and keep a different variable with the required number of zeroes. This will let the number keep its semantic meaning of the number as a number (and allow incrementing, as you said), and when displaying it, pad or fill with zeroes when needed, based on the second value.
How would I remove the chars from the data in this file so I could sum up the numbers?
Alice Jones,80,90,100,95,75,85,90,100,90,92
Bob Manfred,98,89,87,89,9,98,7,89,98,78
I want to do this so for every line it will remove all the chars but not ints.
The following code might be useful to you, try running it once,
public static void main(String ar[])
{
String s = "kasdkasd,1,2,3,4,5,6,7,8,9,10";
int sum=0;
String[] spl = s.split(",");
for(int i=0;i<spl.length;i++)
{
try{
int x = Integer.parseInt(spl[i]);
sum = sum + x;
}
catch(NumberFormatException e)
{
System.out.println("error parsing "+spl[i]);
System.out.println("\n the stack of the exception");
e.printStackTrace();
System.out.println("\n");
}
}
System.out.println("The sum of the numbers in the string : "+ sum);
}
even the String of the form "abcd,1,2,3,asdas,12,34,asd" would give you sum of the numbers
You need to split each line into a String array and parse the numbers starting from index 1
String[] arr = line.split(",");
for(int i = 1; i < arr.length; i++) {
int n = Integer.parseInt(arr[i]);
...
try this:
String input = "Name,2,1,3,4,5,10,100";
String[] strings = input.split(",");
int result=0;
for (int i = 1; i < strings.length; i++)
{
result += Integer.parseInt(strings[i]);
}
You can make use of the split method of course, supplying "," as the parameter, but that's not all.
The trick is to put each text file's line into an ArrayList. Once you have that, move forwars the Pseudocode:
1) Put each line of the text file inside an ArrayList
2) For each line, Split to an array by using ","
3) If the Array's size is bigger than 1, it means there are numbers to be summed up, else only the name lies on the array and you should continue to the next line
4) So the size is bigger than 1, iterate thru the strings inside this String[] array generated by the Split function, from 1 to < Size (this will exclude the name string itself)
5) use Integer.parseInt( iterated number as String ) and sum it up
There you go
Number Format Exception would occur if the string is not a number but you are putting each line into an ArrayList and excluding the name so there should be no problem :)
Well, if you know that it's a CSV file, in this exact format, you could read the line, execute string.split(',') and then disregard the first returned string in the array of results. See Evgenly's answer.
Edit: here's the complete program:
class Foo {
static String input = "Name,2,1,3,4,5,10,100";
public static void main(String[] args) {
String[] strings = input.split(",");
int result=0;
for (int i = 1; i < strings.length; i++)
{
result += Integer.parseInt(strings[i]);
}
System.out.println(result);
}
}
(wow, I never wrote a program before that didn't import anything.)
And here's the output:
125
If you're not interesting in parsing the file, but just want to remove the first field; then split it, disregard the first field, and then rejoin the remaining fields.
String[] fields = line.split(',');
StringBuilder sb = new StringBuilder(fields[1]);
for (int i=2; i < fields.length; ++i)
sb.append(',').append(fields[i]);
line = sb.toString();
You could also use a Pattern (regular expression):
line = line.replaceFirst("[^,]*,", "");
Of course, this assumes that the first field contains no commas. If it does, things get more complicated. I assume the commas are escaped somehow.
There are a couple of CsvReader/Writers that might me helpful to you for handling CSV data. Apart from that:
I'm not sure if you are summing up rows? columns? both? in any case create an array of the target sum counters int[] sums(or just one int sum)
Read one row, then process it either using split(a bit heavy, but clear) or by parsing the line into numbers yourself (likely to generate less garbage and work faster).
Add numbers to counters
Continue until end of file
Loading the whole file before starting to process is a not a good idea as you are doing 2 bad things:
Stuffing the file into memory, if it's a large file you'll run out of memory (very bad)
Iterating over the data 2 times instead of one (probably not the end of the world)
Suppose, format of the string is fixed.
String s = "Alice Jones,80,90,100,95,75,85,90,100,90,92";
At first, I would get rid of characters
Matcher matcher = Pattern.compile("(\\d+,)+\\d+").matcher(s);
int sum = 0;
After getting string of integers, separated by a comma, I would split them into array of Strings, parse it into integer value and sum ints:
if (matcher.find()){
for (String ele: matcher.group(0).split(",")){
sum+= Integer.parseInt(ele);
}
}
System.out.println(sum);
I have sort of a funky question (that I hope hasn't been asked and answered yet). To start, I'll tell you the order of what I'm trying to do and how I'm doing it and then tell you where I'm having a problem:
Convert a string of characters into ASCII numbers
Convert those ASCII numbers into binary and store them in a string
Convert those binary numbers back into ASCII numbers
Convert the ASCII numbers back into normal characters
Here are the methods I've written so far:
public static String strToBinary(String inputString){
int[] ASCIIHolder = new int[inputString.length()];
//Storing ASCII representation of characters in array of ints
for(int index = 0; index < inputString.length(); index++){
ASCIIHolder[index] = (int)inputString.charAt(index);
}
StringBuffer binaryStringBuffer = new StringBuffer();
/* Now appending values of ASCIIHolder to binaryStringBuffer using
* Integer.toBinaryString in a for loop. Should not get an out of bounds
* exception because more than 1 element will be added to StringBuffer
* each iteration.
*/
for(int index =0;index <inputString.length();index ++){
binaryStringBuffer.append(Integer.toBinaryString
(ASCIIHolder[index]));
}
String binaryToBeReturned = binaryStringBuffer.toString();
binaryToBeReturned.replace(" ", "");
return binaryToBeReturned;
}
public static String binaryToString(String binaryString){
int charCode = Integer.parseInt(binaryString, 2);
String returnString = new Character((char)charCode).toString();
return returnString;
}
I'm getting a NumberFormatException when I run the code and I think it's because the program is trying to convert the binary digits as one entire binary number rather than as separate letters. Based on what you see here, is there a better way to do this overall and/or how can I tell the computer to recognize the ASCII characters when it's iterating through the binary code? Hope that's clear and if not I'll be checking for comments.
So I used OP's code with some modifications and it works really well for me.
I'll post it here for future people. I don't think OP needs it anymore because he probably figured it out in the past 2 years.
public class Convert
{
public String strToBinary(String inputString){
int[] ASCIIHolder = new int[inputString.length()];
//Storing ASCII representation of characters in array of ints
for(int index = 0; index < inputString.length(); index++){
ASCIIHolder[index] = (int)inputString.charAt(index);
}
StringBuffer binaryStringBuffer = new StringBuffer();
/* Now appending values of ASCIIHolder to binaryStringBuffer using
* Integer.toBinaryString in a for loop. Should not get an out of bounds
* exception because more than 1 element will be added to StringBuffer
* each iteration.
*/
for(int index =0;index <inputString.length();index ++){
binaryStringBuffer.append(Integer.toBinaryString
(ASCIIHolder[index]));
}
String binaryToBeReturned = binaryStringBuffer.toString();
binaryToBeReturned.replace(" ", "");
return binaryToBeReturned;
}
public String binaryToString(String binaryString){
String returnString = "";
int charCode;
for(int i = 0; i < binaryString.length(); i+=7)
{
charCode = Integer.parseInt(binaryString.substring(i, i+7), 2);
String returnChar = new Character((char)charCode).toString();
returnString += returnChar;
}
return returnString;
}
}
I'd like to thank OP for writing most of it out for me. Fixing errors is much easier than writing new code.
You've got at least two problems here:
You're just concatenating the binary strings, with no separators. So if you had "1100" and then "0011" you'd get "11000011" which is the same result as if you had "1" followed by "1000011".
You're calling String.replace and ignoring the return result. This sort of doesn't matter as you're replacing spaces, and there won't be any spaces anyway... but there should be!
Of course you don't have to use separators - but if you don't, you need to make sure that you include all 16 bits of each UTF-16 code point. (Or validate that your string only uses a limited range of characters and go down to an appropriate number of bits, e.g. 8 bits for ISO-8859-1 or 7 bits for ASCII.)
(I have to wonder what the point of all of this is. Homework? I can't see this being useful in real life.)