How to do character math? - java

I'm not to sure how to use character math. In my program, i have a character array and i have to change the elements of the array, so that its the opposite of the character entered by the user. Example 'a' to 'z'. i guess i can change each element in the array, but that would take forever and would be a waste of time. So far i have tried nothing, i just don't know where to start.
import java.util.*;
public class SecretCodeMachine
{
public static void main(String[]args)
{
SecretCodeMachine a = new SecretCodeMachine();
Scanner in = new Scanner (System.in);
String input = in.nextLine();
String print = a.encodeMessage(input);
System.out.println(print);
}
public String encodeMessage(String pass)
{
char[] j = pass.toCharArray();
String b = new String(j);
return b;
}
}
I have written the encodingMessage() method where all that code would be, im just not sure how i would approach this. Would i most likely use some type of loop?

The simplest solution would be to create a lookup table of valid input characters and what the output character should be. This can be done with either a map or array, that is up to you. Then for each character, you would look it up in the table and place the output character into the new string.
But if you really need to use character math, which I can only assume meaning, converting the character to its corresponding ASCII int value, then doing some math to result in the correct int value of the resulting character. This will be much more complex, but it can be done.

You can condition on whether it is in the first half of the alphabet or the second half, and do arithmetic with characters directly.
import java.util.*;
public class SecretCodeMachine
{
public static void main(String[]args)
{
SecretCodeMachine a = new SecretCodeMachine();
Scanner in = new Scanner (System.in);
String input = in.nextLine();
String print = a.encodeMessage(input);
System.out.println(print);
}
public String encodeMessage(String pass)
{
char[] j = pass.toCharArray();
for (int i = 0; i < j.length; i++) {
// Lower case
if (j[i] >= 'a' && j[i] <= 'z') {
if (j[i] - 'a' <= 13) j[i] = (char) ('z' - (j[i] - 'a'));
else j[i] = (char) ('a' + ('z' - j[i]));
}
// Upper Case
else {
if (j[i] - 'A' <= 13) j[i] = (char) ('Z' - (j[i] - 'A'));
else j[i] = (char) ('A' + ('Z' - j[i]));
}
}
String b = new String(j);
return b;
}
}

this will work for all lowercase and here is a link to the ASCII Table for your reference
for(int i = 0; i < j.length ; i ++){
int f = j[i];
int g = f - 97;
int h = 25 - g * 2;
j[i] += h;
}

Related

Java: Adding Digits Of A String

I have the correct code, I found an answer long ago, however I still don't understand why it works.
class Main {
public static void main(String[] args) {
System.out.println(D5PSum(10));
}
private static int D5PSum(int number) {
String n = Integer.toString(number);
int sum = 0;
for (int i = 0; i < n.length(); i++) {
// (1) WHY DOES THIS NOT WORK
//sum += Integer.parseInt(number.charAt(i));
// (2) MORE IMPORTANTLY WHY DOES THIS WORK
char c = n.charAt(i);
sum += (c-'0');
// (3) WHAT IN THE WORLD IS c-'0'
}
return sum;
}
}
// (1) WHY DOES THIS NOT WORK
because Integer.parseInt(...); is expecting a string as parameter not a char
// (2) MORE IMPORTANTLY WHY DOES THIS WORK
char c = n.charAt(i);
any char is nothing else as an integer mapped to a table of symbols...(ASCII table for example) so this (c - '0') is just another valid mathematical operation
charAt is not a valid method of the primitive type int.
'0' is the character 0, and the character encoding set that Java uses has 0 to 9 in a consecutive block. Therefore c - '0' yields the position of c in that consecutive block which is therefore the value of the digit. (Actually this sort of thing is idiomatic C - goes right back to the 1960s).
You should first convert String to Int.. Please check the below code:
class MainClass {
public static void main(String[] args) {
System.out.println(D5PSum(11));
}
private static int D5PSum(int number) {
String n = Integer.toString(number);
System.out.println(n);
int sum = 0;
for (int i = 0; i < n.length(); i++) {
// (1) WHY DOES THIS NOT WORK
String str = String.valueOf(n.charAt(i));
sum += Integer.parseInt(str);
// (2) MORE IMPORTANTLY WHY DOES THIS WORK
// char c = n.charAt(i);
// sum += (c-'0');
// (3) WHAT IN THE WORLD IS c-'0'
}
return sum;
}
}
1
It doesnt work because Integer.parseInt takes a String and String.charAt returns a char(actar). Integer.parseInt (Character.toString(n.charAt(i))) would Work.
2/3
A char represents a number between 0 and 65535. EACH digit-characters (0-9) has a number in that range which depends on the charset. All digits are typically in a row, for example the character 0 has the value 48, 1 49 and 9 57. So ich you want to know the digit value of a char you simply subtract the character value of 0 from your character. That is the Line c-'0'
// (1) WHY DOES THIS NOT WORK
//sum += Integer.parseInt(number.charAt(i));
number is a variable of primitive data type "int" so number.charAt(i) won't work.
// (2) MORE IMPORTANTLY WHY DOES THIS WORK
char c = n.charAt(i);
n is an instance of String and we are getting the character at i th position in the n string
sum += (c-'0');
// (3) WHAT IN THE WORLD IS c-'0'
for every character there is an ascii code assigned. '0' = 48, 'c' = 99. That's the reason why it works here. when 'c'-'0' is executed, it's equivalent to 99-48
Why convert to a string in the first place? The simplest and fastest way to solve this is without deviation to strings:
private static int D5PSum(int number) {
int v = number, sum = 0;
while (v != 0) {
sum += v % 10;
v /= 10;
}
return sum;
}
If you want your code (the part which does not works to work then do this).
class Main {
public static void main(String[] args) {
System.out.println(D5PSum(10));
}
private static int D5PSum(int number) {
String n = Integer.toString(number);
int sum = 0;
for (int i = 0; i < n.length(); i++) {
sum += Integer.parseInt(n.charAt(i)+"");
}
return sum;
}
}
To get sum of the digits of a string str:
int sum = str.chars().map(Character::getNumericValue).sum();

Decimal to Binary without using in-built functions (like parseInt, Math.pow), etc

I need to create a program to take an input and convert it into binary output. I cannot use in-built functions such as (parseInt, Math.pow, etc.) to do this. I am stuck and need help. This is what I have so far, spread out across 2 java files.
Driver class:
import java.util.*;
public class Driver {
public Driver(){
}
public static void main(String[] args) {
Driver drive = new Driver();
// scanner to read in data from the user
Scanner scanner = new Scanner(System.in);
// instance of the solver class
Solver mySolver = new Solver();
// read in the first number
System.out.print("Enter a number to convert to binary: ");
char [] val1 = scanner.nextLine().toCharArray();
// call solver class method to obtain the number of bits
int numBits = mySolver.howManyBits(val1);
// use the number of bits and the input to get the binary representation
char [] binaryVal1 = mySolver.stringToBinary(val1, numBits);
// print the results
System.out.println(new String(binaryVal1));
// read in the arithmetic expression
System.out.print("Enter an arithmetic expression to convert to binary: ");
char [] val2 = scanner.nextLine().toCharArray();
// call the solver class to solve the expression
char [] result2 = mySolver.solveExpression(val2);
// print the results
System.out.println(new String(result2));
scanner.close();
}
}
Solver class:
import java.util.*;
public class Solver{
private int[] powersOf2;
public Solver() {
// Constructor method
int numPowersOf2 = 16;
powersOf2 = new int[numPowersOf2];
int exponent=1;
for(int count = 1; count <= numPowersOf2; count++){
exponent *= 2;
powersOf2[count] = exponent;
}
}
public static void main(String[] args) {
// Main method for Solver class
Solver solve = new Solver();
}
public int howManyBits(char[] val1) {
// howManyBits method
int decimal = Integer.parseInt(new String(val1));
int logValue = (int) (Math.log(decimal)/Math.log(2));
int numBits = 0;
// Condition block to return number of bits.
if (logValue <= 3) {
numBits = 4;
}
else if (logValue <=7 && logValue > 3) {
numBits = 8;
}
else if (logValue <=15 && logValue > 7) {
numBits = 16;
}
System.out.println("Bits: " + numBits);
return numBits;
}
public char[] stringToBinary(char[] val1, int numBits) {
// stringToBinary method
int decimalNumber = Integer.parseInt(new String(val1));
char[] binaryVal1 = new char[numBits];
int remainder = 0;
for (int count = 0; decimalNumber > 0; count++) {
remainder = decimalNumber % 2;
decimalNumber /= 2;
char[] place = String.valueOf(remainder).toCharArray();
binaryVal1[count] = place[count];
System.out.println(binaryVal1[count]);
}
return binaryVal1;
}
public char[] twosComplement(char[] val1){
return val1;
}
public char[] solveExpression(char[] val2) {
// solveExpression method
return null;
}
}
Now I am quite confused about what do you mean by "built-in functions". In that case, is println one of them? or Scanner.nextInt? I think the word "built-in function" is not very clear. I think it maybe means the functions that has the word int.
My idea is that you continuously divide the decimal number by 2 and store the remainder. And then you display the remainders in reverse order. That means you are probably going to use a Stack. This is the best method I can think of:
Stack<Integer> remainders = new Stack<> ();
Scanner s = new Scanner (System.in);
int decimalNumber = s.nextInt();
while (decimalNumber >= 2) {
remainders.push(decimalNumber % 2);
decimalNumber /= 2;
}
remainders.push(decimalNumber);
StringBuilder builder = new StringBuilder ();
int size = remainders.size();
for (int i = 0 ; i < size ; i++) {
builder.append(remainders.pop());
}
System.out.println(builder);
P.S. Technically, functions are routines that are not in ny classes. Methods must be in one class. Which means in this case you can just use Integer.toBinaryString!
Just kidding, I know what you mean.
If you have learned about bit manipulation yet, then you can find the rightmost bit by doing a binary AND with 1 (x & 1), then right-shift the value using the unsigned right-shift operator (x >>> 1), and keep doing it until number is 0.
See The Oracle Java Tutorials Bitwise and Bit Shift Operators or the Wikipedia Bitwise operation.
Depending on whether you're allowed to use the StringBuilder class, here are two versions:
// Using StringBuilder
public static String toBinary(int number) {
StringBuilder buf = new StringBuilder();
do {
buf.append((number & 1) == 0 ? '0' : '1');
number >>>= 1;
} while (number != 0);
return buf.reverse().toString();
}
// Using character array
public static String toBinary(int number) {
char[] buf = new char[32];
int i = buf.length;
do {
buf[--i] = (number & 1) == 0 ? '0' : '1';
number >>>= 1;
} while (number != 0);
return new String(buf, i, buf.length - i);
}
Of course, you'll first have to parse a string to an integer, which is simple enough:
public static int toInt(String text) {
if (text.isEmpty())
throw new IllegalArgumentException();
int num = 0;
for (char c : text.toCharArray()) {
if (c < '0' || c > '9')
throw new IllegalArgumentException();
num = num * 10 + c - '0';
}
return num;
}
You can then combine them:
public static String toBinary(String text) {
return toBinary(toInt(text));
}

reversing every odd string and adding them together

i want to reverse every odd pair of strings and them add them together with the even pair.
for example the string 123456789 would turn into 213465789 and then adding them together would give 21+34+65+78+9 which = 207.
my current code is
public static void main(String[] args) {
String Num = "123456789";
System.out.println(reverse(Num) + ".");
}
public static int reverse(String a) {
String newa = "";
String revString = "";
char ch;
for (int i = 0; i < a.length(); i=i+4) {
newa = (a.substring(i, i + 2));
ch = newa.charAt(i);
revString = ch + revString;
}
}
I do have an general idea which is to reverse every second pair of strings and place them back into a new string that would be "213465789". Then split the string into pairs and add them up and whatever other operation like /, * and % but i cant seem to write my code
Thanks in advance
try this -
int pairCout=0;
int sum =0;
for (int i = 0; i < a.length();i+=2) {
String newa = a.substring(i, (i + 2)<a.length()?(i+2):a.length());
pairCout++;
if(pairCout%2 ==0){ // EVEN/ODD separation
String reverse = new StringBuilder(newa ).reverse().toString();
sum+=Integer.parseInt(reverse); // SUMMATION
}else{
sum+=Integer.parseInt(newa ); // SUMMATION
}
}
Just an approach - OUTPUT - 207
Simply algo would be something like
String Num = "123456789";
Loop for(int i= 0 to n-3;i=i+2) - to reverse the string
swap i with i+1 - this give alternate rev string
again for(int i= 0 to n-3;i=i+2) - to add the sum
sum = sum + ((chatAt(i)-'0')*10+(charAt(i+1)-'0')) - typecast from char to int using [char]-'0' logic, for String "21", logic would be to have (2*10+1)

Incrementing charaters past 'Z' in Java like a Spreadsheet

I didn't start too long ago with programming, and currently I need a method to produce an array, containing a character which is comes after the previous character. It should start with an 'A' at 0, then a B at '1' etc.. The hard part is making it so that after the 'Z' comes 'AA'.
What I came up with:
public static String[] charArray(int length)
{
String[] res = new String[length];
for(int i = 0; i < length; i++)
{
String name = "";
int colNumber = i;
while(colNumber > 0)
{
char c = (char) ('A' + (colNumber % 26));
name = c + name;
colNumber = colNumber / 26;
}
res[i] = name;
}
return res;
}
This works fine for the first 26 letters of the alphabet, but it produces "... Y, Z, BA, BB, BC..." instead of "... Y, Z, AA, AB, AC..."
What's wrong? Or are there any more efficient or easier ways to do this?
Thanks in advance!
You had a nice start. Instead of running through the while loop this example basically calculates the value of C based on the number % 26
Then the letter is added (concatenated) to the value within the array at the position: (index / 26) - 1 which ensures it's keeping up with the changes over time.
When iterating through on the first go, you'll have only one letter in each slot in the array A B C etc.
Once you've run through the alphabet, you'll then have an index that looks backwards and adds the current letter to that value.
You'll eventually get into AAA AAB AAC etc. or even more.
public static String[] colArray(int length) {
String[] result = new String[length];
String colName = "";
for(int i = 0; i < length; i++) {
char c = (char)('A' + (i % 26));
colName = c + "";
if(i > 25){
colName = result[(i / 26) - 1] + "" + c;
}
result[i] = colName;
}
return result;
}
Try like this:
public static String[] charArray(int length)
{
String[] res = new String[length];
int counter = 0;
for(int i = 0; counter < length; i++)
{
String name = "";
int colNumber = i;
while(colNumber > 0 && colNumber % 27 != 0)
{
char c = (char) ('A' + ((colNumber) % 27) - 1);
name = c + name;
colNumber = colNumber / 27;
}
res[counter] = name;
if (i % 27 != 0) {
counter++;
}
}
return res;
}
Basically your algorithm skipped all elements starting with an A (A, AA, AB, ...) (because an A is created when colNumber is 0, but this never happens because your while terminates in that case). Taking modulo of 27 and then actually subtracting 1 after from the char fixes this issue. Then we use counter as index as otherwise we would end up with some empty elements in the array (the ones where i would be i % 27 == 0).
This solution works for me. Having 26 vocabulary letters and knowing that 65 is the char 'A' in ASCII table, we can get the incrementing with this recursive method...
private fun indexLetters(index: Int, prefix: String = "") : String {
val indexSuffix:Int = index.rem(26)
val suffix = (65 + indexSuffix).toChar().toString().plus(".")
val newPrefix = suffix.plus(prefix)
val indexPrefix: Int = index / 26
return if (indexPrefix > 0) {
indexLetters(indexPrefix - 1, newPrefix)
} else {
newPrefix
}
}
You can call this kotlin method like
indexLetters(0) //To get an 'A'
indexLetters(25) //To get a 'Z'
indexLetters(26) //To get an 'A.A'
etcetera...
from an array iteration, depending of your requirements

Converting alphanumeric to ascii and incrementing

I'm stumped on how to convert 3 letters and 3 numbers to ascii and increment them by one...it's the old next-license-plate problem. Can anyone give me a nudge in the right direction?
This problem actually have real applications. I wrote an account number generator that works just like this. I modified it to your format. Here you go,
public class LicenseNumber {
int numericSum;
int letterSum;
public LicenseNumber() {
numericSum = letterSum = 0;
}
public LicenseNumber(String number) {
if (!number.matches("^[A-Za-z]{3}[0-9]{3}$"))
throw new IllegalArgumentException("Number doesn't match license format");
numericSum = Integer.valueOf(number.substring(3));
letterSum = value(number, 0) * 26 * 26 + value(number, 1) * 26 +
value(number, 2);
}
public void increment() {
increment(1);
}
public void increment(int inc) {
numericSum += inc;
if (numericSum >= 1000) {
letterSum += numericSum/1000;
numericSum %= 1000;
}
}
public String toString() {
char[] letters = new char[3];
int n = letterSum;
for (int i = 0; i < 3; i++) {
letters[2-i] = (char)('A' + (n%26));
n /= 26;
}
return new String(letters) + String.format("%03d", numericSum);
}
private int value(String s, int index) {
return Character.toUpperCase(s.charAt(index)) - 'A';
}
/**
* Example
*/
public static void main(String[] args) {
LicenseNumber lic = new LicenseNumber("ABC999");
for (int i=0; i < 100; i++) {
lic.increment(500);
System.out.println(lic);
}
}
}
String str = "abc123"
String newstr = "";
for(int i=0; i<str.length(); i++) {
newstr += (char) (str.charAt(i) + 1);
}
// newstr now is "bcd234"
Note that this does not handle the characters 'z','Z' or '9' the way you would want. But it should give you a start.
Also note that using StringBuilder to create newstr would be more efficient.
I guess,
char c='A';
int no=97;
System.out.println( (++c) + " " + (char)++no);
You can do this by converting your String of letters and numbers to a char[]. Once you have done that you can iterate over the array and ++ each.
You're making strings like this: "AAA000", "AAA001", ..., "AAA999", "AAB000", ..., "ZZZ999", right?
Think of it like a number system where the different columns don't use the same number of digits. So where our numbers are 10-10-10-10, your numbers are 26-26-26-10-10-10. Use an underlying integer which you increment, then convert to letters and digits by dividing and taking the modulo successively by 10, 10, 10, 26, 26, 26.
To convert a license plate to its underlying integer, multiply out the letter position (A == 0, B == 1, etc) by the proper power of 26, and the digits by the proper power of 10, and add them all together.
An easy way to generate plate numbers would be to have an integer variable which gets incremented and three integer variables corresponding to the letters, something like this, please modify where appropriate. One trick is to use String.format which seamlessly converts between an integer and its char counterpart (you can also use casts.)
class plateGenerator {
int minLetter = "A".charAt(0);
int maxLetter = "Z".charAt(0);
int curLetter1 = minLetter;
int curLetter2 = minLetter;
int curLetter3 = minLetter;
int number = 0;
public String generatePlate() {
String plate = String.format("%c%c%c-%03d",curLetter1,
curLetter2,curLetter3,number);
increment();
return plate;
}
private void increment() {
number++;
if (number == 1000) {
number = 0;
curLetter1++;
}
if (curLetter1 > maxLetter) {
curLetter1 = minLetter;
curLetter2++;
}
if (curLetter2 > maxLetter) {
curLetter2 = minLetter;
curLetter3++;
}
if (curLetter3 > maxLetter) {
curLetter3 = minLetter;
number++;
}
}
public static void main(String[] args) {
plateGenerator pg = new plateGenerator();
for (int i = 0; i < 50000; i++) {
System.out.println(pg.generatePlate());
}
}
}
I haven't seen any code samples for general solutions for incrementing alphanumeric strings so I though I'd post mine.
This takes a string of any length with any ordering of alpha numeric characters, converts them to upper case and increments it by one (as if it were base 26). It also throws an exception if the numbers wrap. Its really up to you if wrapping makes sense...
private static string IncrementAlphaNumericString(string alphaNumericString)
{
char[] an = alphaNumericString.ToCharArray();
int i = an.Length - 1;
while (true)
{
if (i <= 0)
throw new Exception("Maxed out number!!!");
an[i]++;
if (an[i] - 1 == '9')
{
an[i] = 'A';
}
if (an[i] - 1 == 'Z')
{
an[i] = '0';
i--;
continue;
}
return new string(an);
}
}

Categories