What i've done so far:
public static String convert(int base, int target , String number) {
ArrayList<Integer> numbers= new ArrayList<Integer>();
for(int i=0;i<number.length();i++) {
char check=number.charAt(i);
if(check>='A') {
numbers.add(Character.getNumericValue(check-'A'+1));
}
else {
numbers.add(Character.getNumericValue(check));
}
}
int answer_10 = 0;
for(int i=0;i<number.length();i++) {
answer_10 += Math.pow(numbers.get(number.length()-i-1), base);
}
String answer_target ="";
while(answer_10>0) { // I need help on this part
for(int i=0;i>0;i++) {
if(9*Math.pow(target, i)-answer_10<0) {
i++;
}
else {
for(int j=9;j<=0;j--) {
if(j*Math.pow(target, i)-answer_10<0) {
j-=1;
if(j<=10) {
answer_target += j*Math.pow(target, i);
}
else {
answer_target += j-'A'+1 ;
}
answer_10 -= j*Math.pow(target, i);
break;
}
}
}
}
}
return answer_target;
}
I need help on the part that converts the number from base 10 to base x as a string.
The question limits 2<=x<=20.
I couldn't use the built-in converting function by java, as the question asked not to.
Math.pow isn't a good choice for this problem. It is better to use simple multiply /divide cycle.
public static String convert(int base, int target, String number) {
if (base < 2 || base > 20)
throw new IllegalArgumentException("Invalid base "+base);
if (target < 2 || target > 20)
throw new IllegalArgumentException("Invalid base "+target);
int numberStrLen = number.length();
int numberValue = 0;
for (int i = 0; i < numberStrLen; i++) {
char ch = Character.toLowerCase(number.charAt(i));
int digit;
if (ch >= '0' && ch <= '9')
digit = ch - '0';
else if (ch >= 'a')
digit = ch - 'a' + 10;
else
throw new IllegalArgumentException("Invalid character "+ch+" for base "+base);
if (digit >= base)
throw new IllegalArgumentException("Invalid character "+ch+" for base "+base);
numberValue = numberValue * base + digit; // <= multiply cycle
}
if (numberValue < 0)
throw new IllegalArgumentException("Signed value: "+numberValue+" for "+number);
StringBuilder sb = new StringBuilder();
while (numberValue != 0) {
int digit = numberValue % target;
numberValue = numberValue / target; // <= divide cycle
char ch;
if (digit < 10)
ch = (char)(digit + '0');
else
ch = (char)(digit - 10 + 'a');
sb.insert(0, ch);
}
if (sb.length() == 0)
return "0";
else
return sb.toString();
}
And don't forget about int overflow (wraparound ). Maybe use long or even BigInteger?
Related
I have a String of a length of more than 1000 character. In this string i have to print 1st character after that every 5th character.
I tried writing a program to iterate from 0th character to last character and have a count variable.
If count is equal to 5. I am printing the character and count is initializing with 0.
private static String getMaskedToken(String token) {
if (token == null)
return null;
char[] charArray = token.toCharArray();
int length = token.length();
StringBuilder sb = new StringBuilder();
int count = 0;
for (int i = 0; i < length; i++) {
count++;
if (i == 0 || i == length - 1) {
sb.append(charArray[i]);
} else if (count == 5) {
sb.append(charArray[i]);
count=0;
} else if(count < 5 && i == length-1){
sb.append(charArray[i]);
}else {
sb.append('*');
}
}
return sb.toString();
}
Need to print last character if count is less than 5 of last
iteration.
If String of length 9, "12345678" then actual output will be like
1***5**8
If String of length 9, "123456789abcd" then actual output will be
like 1***5****a**d
String output = "";
for (int i = 0; i < str.length(); i++) {
if (i == 0) {
output += str.charAt(i);
output += "***";
output += str.charAt(4);
i = 4;
} else if ((i - 4) % 5 == 0) {
output += str.charAt(i);
} else if (i == str.length()-1) {
output += str.charAt(i);
} else {
output += "*";
}
}
System.out.println(output);
}
This will print 1***5****a**d for string "123456789abcd".
try this code:
public void printFirstAndEveryFifthCharecter(String str)
{
for (int i = 0 ; i < str.length() ; i++)
{
if ((i+1) == 1 | (i+1) % 5 == 0) {
System.out.print(str.charAt(i) + "***");
}
}
if (str.length() % 5 > 0) {
System.out.print(str.charAt(str.length() - 1));
}
}
Your code should work fine. Here's an alternative without using StringBuilder and with fewer checks.
private static String getFirstFifthLast(String str) {
String[] strArray = str.split(""); //returns an array of strings with length 1
int arrayLength = strArray.length;
String result = strArray[0]; //append the first element
//append element if it is in 5th position, append "*" otherwise
for (int i = 0; i < arrayLength; i++) {
if ((i + 1) % 5 == 0) {
result += strArray[i];
} else {
result += "*";
}
}
result += strArray[arrayLength - 1]; //append the last element
return result;
}
Try this code,
private void printEvery5thCharacter(String str) {
for (int i = 1; i < str.length() - 1; i += 5) {
System.out.print(str.charAt(i - 1) + "***");
if (i == 1) {
i = 0;
}
}
if (str.length() % 5 > 0) {
System.out.print(str.charAt(str.length() - 1));
}
}
I have converted some decimal numbers into the binary, octal and hexadecimal system. For that, I didn't have to use any collections and libraries. So now I need to change my implementation because I used String for storing the result, while I supposed to use a char array.
My current implementation:
public static String convertDecimal(int number, int base){
String result = "";
while (number > 0) {
if (base == 16) {
int hexalNumber = number % base;
char hexDigit = (hexalNumber <= 9 && hexalNumber > 0) ?
(char) (hexalNumber + '0') :
(char) (hexalNumber - 10 + 'A');
result = hexDigit + result;
number = number / base;
}
if (base == 8 || base == 2) {
int remainder = number % base;
result = remainder + result;
number = number / base;
}
}
return result;
}
How can I change my implementation in order to return char[] from the method? Should I completely change the logic of my conversion algorithm?
I would be grateful for any help.
String has a method for converting itself to a char[], just use it:
return result.toCharArray();
If they want an array of char, they probably won't like just a
return result.toCharArray();
As arrays are of fixed size, one could first count the digits:
public static char[] convertDecimal(int number, int base) {
if (number < 0) {
char[] positiveResult = convertDecimal(-number, base);
char[] negativeResult = ...
return negativeResult;
} else if (number == 0) {
return new char[] { '0' };
}
int digits = 0;
int n = number;
while (n != 0) {
++digits;
n /= base;
}
char[] result = new char[digits];
for (int i = 0; i < digits; ++i) {
... result[... i ...] = ...; ++i
}
return result;
}
I have tested this in your code:
convertDecimal(7856421, 16);
For this call and editing your code as following (I have not deleted any line, only added I have added the car[]):
public static String convertDecimal(int number, int base) {
char[] resultChar = new char[0];
String result = "";
while (number > 0) {
if (base == 16) {
int hexalNumber = number % base;
char hexDigit = (hexalNumber <= 9 && hexalNumber > 0) ? (char) (hexalNumber + '0')
: (char) (hexalNumber - 10 + 'A');
result = hexDigit + result;
int totalLength = resultChar.length + 1;
char[] aux = new char[totalLength];
int i = 0;
for (i = 0; i < resultChar.length; i++) {
aux[i] = resultChar[i];
}
aux[totalLength - 1] = hexDigit;
resultChar = aux;
number = number / base;
}
if (base == 8 || base == 2) {
int remainder = number % base;
result = remainder + result;
number = number / base;
}
}
return result;
}
Yo have in resultChar[] the result inverted (in this case you get 77E125 and the char[] has [5, 2, 1, E, 7, 7]). now you only need to return it inverted.
How to calculate the 2's Complement of a Hex number in Android/Java.
For Example :
String x = 10011010;
1's complement of x = 01100101;
2's complement is 01100110;
How I can pro-grammatically achieve in Java?
I had tried the following code to convert the binary to its 1's compliment:
public String complementFunction(String bin) {
String ones = "";
for (int i = 0; i < bin.length(); i++) {
ones += flip(bin.charAt(i));
}
return ones;
}
// Returns '0' for '1' and '1' for '0'
public char flip(char c) {
return (c == '0') ? '1' : '0';
}
But I'm not able to get its two's complement.
Thanks for your help everyone.
I got the solution and it is as follows :
public String twosCompliment(String bin) {
String twos = "", ones = "";
for (int i = 0; i < bin.length(); i++) {
ones += flip(bin.charAt(i));
}
int number0 = Integer.parseInt(ones, 2);
StringBuilder builder = new StringBuilder(ones);
boolean b = false;
for (int i = ones.length() - 1; i > 0; i--) {
if (ones.charAt(i) == '1') {
builder.setCharAt(i, '0');
} else {
builder.setCharAt(i, '1');
b = true;
break;
}
}
if (!b)
builder.append("1", 0, 7);
twos = builder.toString();
return twos;
}
// Returns '0' for '1' and '1' for '0'
public char flip(char c) {
return (c == '0') ? '1' : '0';
}
Thanks to all for helping.
This wikipedia section explains an easy way to get the 2's complement: Get the 1's complement, then add 1 (in binary logic). So you can use the complementFunction you already have, then go through the String backwards. If you find a 1, flip it and continue. If you find a 0, flip it and stop.
String twos = "";
for (int i = bin.length() - 1; i >= 0; i--) {
if (bin.charAt(i) == '1') {
twos = "0" + twos;
} else {
twos = bin.substring(0, i) + "1" + two;
break;
}
twos = flip(bin.charAt(i));
}
return twos;
#BackSlash's comment above is intriguing. This answer is the full program written based on this idea:
import java.time.temporal.ValueRange;
import java.util.Scanner;
//This program generates convert decimal to binary
public class ConvertDecimalToBinary {
public static int getNumberOfBytes(int n) {
int bytes = 0;
ValueRange byteRange = ValueRange.of(Byte.MIN_VALUE, Byte.MAX_VALUE);
ValueRange shortRange = ValueRange.of(Short.MIN_VALUE, Short.MAX_VALUE);
ValueRange intRange = ValueRange.of(Integer.MIN_VALUE, Integer.MAX_VALUE);
if (byteRange.isValidValue(n)) {
bytes = 1;
} else if (shortRange.isValidValue(n)) {
bytes = 2;
} else if (intRange.isValidValue(n)) {
bytes = 4;
}
return bytes;
}
//Convert a positive decimal number to binary
public static String convertPositiveNumberToBinary(int n, int bytes,boolean reverse) {
int bits = 8 * bytes;
StringBuilder sb = new StringBuilder(bits); //in-bits
if (n == 0) {
sb.append("0");
} else {
while (n > 0) {
sb.append(n % 2);
n >>= 1; //aka n/2
}
}
if (sb.length() < bits) {
for (int i = sb.length(); i < bits; i++) {
sb.append("0");
}
}
if (reverse) {
return sb.toString();
} else {
return sb.reverse().toString();
}
}
//Convert negative decimal number to binary
public static String convertNegativeNumberToBinary(int n, int bytes) {
int m = -n; //conver to positve
String binary = convertPositiveNumberToBinary(m,bytes,true);
int len = binary.length();
StringBuilder sb = new StringBuilder(len); //in-bits
boolean foundFirstOne = false;
for(int i=0; i < len;i++) {
if(foundFirstOne) {
if(binary.charAt(i) == '1') {
sb.append('0');
}
else {
sb.append('1');
}
}
else {
if(binary.charAt(i) == '1') {
foundFirstOne = true;
}
sb.append(binary.charAt(i));
}
}
return sb.reverse().toString();
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while(scanner.hasNextInt()) {
int n = scanner.nextInt();
int bytes = getNumberOfBytes(n);
String binary;
if(n >= 0) {
binary = convertPositiveNumberToBinary(n,bytes,false);
}
else {
binary = convertNegativeNumberToBinary(n,bytes);
}
System.out.println(String.format("Binary representation of {%s} is {%s}",n,binary));
}
scanner.close();
}
}
I would like multiply letter by number in a String and return other String.
I don't know how to concat it when number is higher than 9 and then multiply
eg.
String ="a2b10" convert to String ="aabbbbbbbbbb"
string can have different values: "a2b15", "a16b4c1","a11b14c5"
below I made it only for one letter and one number eg. a1b8, a4b7v3
import javafx.util.converter.CharacterStringConverter;
public class Test {
public static void main(String[] args) {
String txt = "a3b2";
char ch;
for (int i = 0; i < txt.length(); i++) {
ch = txt.charAt(i);
if (((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))) {
} else if (ch >= '0' && ch <= '9')
{
int count = Character.getNumericValue(ch);
for (int j = 0; j < count; j++) {
System.out.print(txt.charAt(i - 1));
}
} else
System.out.println("not a letter");
}
}
}
In this case it's easier to use regex and group-matching to extract the letter and the number that's following it:
public static void main(String[] args) {
String txt = "a3b10";
String patt = "([a-z])([0-9]*)"; // ([a-z]) will be the first group and ([0-9]*) will be the second
Pattern pattern = Pattern.compile(patt);
Matcher matcher = pattern.matcher(txt);
while(matcher.find()) {
String letter = matcher.group(1);
String number = matcher.group(2);
int num = Integer.valueOf(number);
while (num > 0) {
System.out.print(letter);
num--;
}
}
}
OUTPUT
aaabbbbbbbbbb
You can do it like this ...
public class Test {
public static void main(String[] args) {
String txt = "a10b10";
char ch;
char tempChar = ' ';
int temp = -1;
for (int i = 0; i < txt.length(); i++) {
ch = txt.charAt(i);
if (((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))) {
temp = -1;
tempChar = ch;
} else if (ch >= '0' && ch <= '9') {
int count = Character.getNumericValue(ch);
if (temp != -1) {
count = ((10*temp) - temp);
}
for (int j = 0; j < count; j++) {
//System.out.print(txt.charAt(i - 1));
System.out.print(tempChar);
}
temp = count;
} else {
System.out.println("not a letter");
}
}
}
}
When you're looking for numbers and you find one, keep looking for numbers until you find a letter or the end of the string.
Its supose to tell me if a card is valid or invalid using luhn check
4388576018402626 invalid
4388576018410707 valid
but it keeps telling me that everything is invalid :/
Any tips on what to do, or where to look, would be amazing. I have been stuck for a few hours.
It would also help if people tell me any tips on how to find why a code is not working as intended.
im using eclipse and java
public class Task11 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Enter a credit card number as a long integer: ");
long number = input.nextLong();
if (isValid(number)) {
System.out.println(number + " is valid");
} else {
System.out.println(number + " is invalid");
}
}
public static boolean isValid(long number) {
return (getSize(number) >= 13) && (getSize(number) <= 16)
&& (prefixMatched(number, 4) || prefixMatched(number, 5) || prefixMatched(number, 6) || prefixMatched(number, 37))
&& (sumOfDoubleEvenPlace(number) + sumOfOddPlace(number)) % 10 == 0;
}
public static int sumOfDoubleEvenPlace(long number) {
int result = 0;
long start = 0;
String digits = Long.toString(number);
if ((digits.length() % 2) == 0) {
start = digits.length() - 1;
} else {
start = digits.length() - 2;
}
while (start != 0) {
result += (int) ((((start % 10) * 2) % 10) + (((start % 10) * 2) / 2));
start = start / 100;
}
return result;
}
public static int getDigit(int number) {
return number % 10 + (number / 10);
}
public static int sumOfOddPlace(long number) {
int result = 0;
while (number != 0) {
result += (int) (number % 10);
number = number / 100;
}
return result;
}
public static boolean prefixMatched(long number, int d) {
return getPrefix(number, getSize(d)) == d;
}
public static int getSize(long d) {
int numberOfDigits = 0;
String sizeString = Long.toString(d);
numberOfDigits = sizeString.length();
return numberOfDigits;
}
public static long getPrefix(long number, int k) {
String size = Long.toString(number);
if (size.length() <= k) {
return number;
} else {
return Long.parseLong(size.substring(0, k));
}
}
}
You should modiffy your isValid() method to write down when it doesn't work, like this:
public static boolean isValid(long number) {
System.err.println();
if(getSize(number) < 13){
System.out.println("Err: Number "+number+" is too short");
return false;
} else if (getSize(number) > 16){
public static boolean isValid(long number) {
System.err.println();
if(getSize(number) < 13){
System.out.println("Err: Number "+number+" is too short");
return false;
} else if (getSize(number) > 16){
System.out.println("Err: Number "+number+" is too long");
return false;
} else if (! (prefixMatched(number, 4) || prefixMatched(number, 5) || prefixMatched(number, 6) || prefixMatched(number, 37)) ){
System.out.println("Err: Number "+number+" prefix doesn't match");
return false;
} else if( (sumOfDoubleEvenPlace(number) + sumOfOddPlace(number)) % 10 != 0){
System.out.println("Err: Number "+number+" doesn't have sum of odd and evens % 10. ");
return false;
}
return true;
}
My guess for your problem is on the getPrefix() method, you should add some logs here too.
EDIT: so, got more time to help you (don't know if it's still necessary but anyway). Also, I corrected the method I wrote, there were some errors (like, the opposite of getSize(number) >= 13 is getSize(number) < 13)...
First it will be faster to test with a set of data instead of entering the values each time yourself (add the values you want to check):
public static void main(String[] args) {
long[] luhnCheckSet = {
0, // too short
1111111111111111111L, // too long (19)
222222222222222l // prefix doesn't match
4388576018402626l, // should work ?
};
//System.out.print("Enter a credit card number as a long integer: ");
//long number = input.nextLong();
for(long number : luhnCheckSet){
System.out.println("Checking number: "+number);
if (isValid(number)) {
System.out.println(number + " is valid");
} else {
System.out.println(number + " is invalid");
}
System.out.println("-");
}
}
I don't know the details of this, but I think you should work with String all along, and parse to long only if needed (if number is more than 19 characters, it might not parse it long).
Still, going with longs.
I detailed your getPrefix() with more logs AND put the d in parameter in long (it's good habit to be carefull what primitive types you compare):
public static boolean prefixMatched(long number, long d) {
int prefixSize = getSize(d);
long numberPrefix = getPrefix(number, prefixSize);
System.out.println("Testing prefix of size "+prefixSize+" from number: "+number+". Prefix is: "+numberPrefix+", should be:"+d+", are they equals ? "+(numberPrefix == d));
return numberPrefix == d;
}
Still don't know what's wrong with this code, but it looks like it comes from the last test:
I didn't do it but you should make one method from sumOfDoubleEvenPlace(number) + sumOfOddPlace(number)) % 10 and log both numbers and the sum (like i did in prefixMatched() ). Add logs in both method to be sure it gets the result you want/ works like it should.
Have you used a debugger ? if you can, do it, it can be faster than adding a lot of logs !
Good luck
EDIT:
Here are the working functions and below I provided a shorter, more efficient solution too:
public class CreditCardValidation {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int count = 0;
long array[] = new long [16];
do
{
count = 0;
array = new long [16];
System.out.print("Enter your Credit Card Number : ");
long number = in.nextLong();
for (int i = 0; number != 0; i++) {
array[i] = number % 10;
number = number / 10;
count++;
}
}
while(count < 13);
if ((array[count - 1] == 4) || (array[count - 1] == 5) || (array[count- 1] == 3 && array[count - 2] == 7)){
if (isValid(array) == true) {
System.out.println("\n The Credit Card Number is Valid. ");
} else {
System.out.println("\n The Credit Card Number is Invalid. ");
}
} else{
System.out.println("\n The Credit Card Number is Invalid. ");
}
in.close();
}
public static boolean isValid(long[] array) {
int total = sumOfDoubleEvenPlace(array) + sumOfOddPlace(array);
if ((total % 10 == 0)) {
for (int i=0; i< array.length; i++){
System.out.println(array[i]);}
return true;
} else {
for (int i=0; i< array.length; i++){
System.out.println(array[i]);}
return false;
}
}
public static int getDigit(int number) {
if (number <= 9) {
return number;
} else {
int firstDigit = number % 10;
int secondDigit = (int) (number / 10);
return firstDigit + secondDigit;
}
}
public static int sumOfOddPlace(long[] array) {
int result = 0;
for (int i=0; i< array.length; i++)
{
while (array[i] > 0) {
result += (int) (array[i] % 10);
array[i] = array[i] / 100;
}
}
System.out.println("\n The sum of odd place is " + result);
return result;
}
public static int sumOfDoubleEvenPlace(long[] array) {
int result = 0;
long temp = 0;
for (int i=0; i< array.length; i++){
while (array[i] > 0) {
temp = array[i] % 100;
result += getDigit((int) (temp / 10) * 2);
array[i] = array[i] / 100;
}
}
System.out.println("\n The sum of double even place is " + result);
return result;
}
}
I also found a solution with less lines of logic. I know you're probably searching for an OO approach with functions, building from this could be of some help.
Similar question regarding error in Luhn algorithm logic:
Check Credit Card Validity using Luhn Algorithm
Link to shorter solution:
https://code.google.com/p/gnuc-credit-card-checker/source/browse/trunk/CCCheckerPro/src/com/gnuc/java/ccc/Luhn.java
And here I tested the solution with real CC numbers:
public class CreditCardValidation{
public static boolean Check(String ccNumber)
{
int sum = 0;
boolean alternate = false;
for (int i = ccNumber.length() - 1; i >= 0; i--)
{
int n = Integer.parseInt(ccNumber.substring(i, i + 1));
if (alternate)
{
n *= 2;
if (n > 9)
{
n = (n % 10) + 1;
}
}
sum += n;
alternate = !alternate;
}
return (sum % 10 == 0);
}
public static void main(String[] args){
//String num = "REPLACE WITH VALID NUMBER"; //Valid
String num = REPLACE WITH INVALID NUMBER; //Invalid
num = num.trim();
if(Check(num)){
System.out.println("Valid");
}
else
System.out.println("Invalid");
//Check();
}
}