I am working on a homework assignment which encodes and decodes letters to int's and vice versa. The first encoding loop I have works great!
public static String Encode(String msg){
String result="";
String m = msg.toUpperCase();
char c;
int x;
for (int i = 0; i<m.length(); i++){
c = m.charAt(i);
x = c;
if (x == 32){
x = 0;
} else{
x -= 64;
if (x < 1 || x > 26){
x = 99;
}
}
result += String.valueOf(x) + " ";
}
return result;
}
It takes the string msg and runs a for loop to convert it into integer equivalent. My issue is the decoding. Essentially, the numbers you input would be entered in with a comma in between each number. I would then take the message into an array and split it to remove the commas. Then I would take it and read each value in a for loop and display the letter equivalent. This is where I am stuck. I understand the logic. It's basically reverse of the first loop, but I cannot seem to effectively code it. Here is what I have:
public static String Decode(String msg){
String result = "";
String m = msg;
char c;
int x;
String[] nums = msg.split(",");
for (int i = 0; i<nums.length; i++){
String num = nums[i];
x = Integer.parseInt(num);
if(x <= 0 || x > 26){
x=-1;
}
result += String.valueOf((char)(x + 64)) + " ";
}
return result;
}
I am having issues with reading the length of the nums array. I haven't had much luck with the rest of it. I understand that you have to parse the integers as well. Any insight into completing this would be greatly appreciated!
Since it's homework, I'll just give you the next step; hopefully you can figure it out from there :)
In your for loop:
String num = nums[i];
x = Integer.parseInt(num);
Related
We don't know the string length until the user enters it but the input format is like number-number-number...
The numbers don't have the same number of digits.
Consider this input
10000-20-150-2-12345-2-1-450000-30-2-50
I'm only allowed to use Scanner(System.in) and save this in a string but not allowed to use parseInt or Integer.valueOf or toCharArray or arrays or split function to extract the numbers into an array.
How can I make a split function and use it?
I thought about for loop and charAt(i)=='-' though but I don't know how to get the numbers.
In order to parse a string into a int, you can use :
// Parse string to int without using Integer.parseInt() or Integer.valueOf()
public static int stringToInteger(String str) {
int answer = 0, factor = 1;
for (int i = str.length()-1; i >= 0; i--) {
answer += (str.charAt(i) - '0') * factor; // '0' is to get the ascii code of 0
factor *= 10;
}
return answer;
}
In your processing code :
You can know the result array length with (java 8) :
int[] result = new int[userInput.chars().filter(ch -> ch == '-').count() + 1];
And you just have to iterate over the userInput String using charAt(n) method and stock the char in a StringBuilder until you get a "-", and then call the stringToInteger method to add the int in the array :
StringBuilder sb = new StringBuilder();
int resultIndex = 0;
char c;
for(int i=0 ; i< userInput.length(); i++) {
char c = userInput.charAt(i);
if(c == '-') {
result[resultIndex++] = stringToInteger(sb.toString());
sb.setLength(0); // Empty the stringBuilder
}
else {
sb.append(c); // Add char in the stringBuilder
}
}
Here's an example using nothing fancy, just String.charAt():
String input = "10000-20-150-2-12345-2-1-450000-30-2-50";
String curValue = "";
for(int i=0; i<input.length(); i++) {
char c = input.charAt(i);
if (!(c == '-')) {
curValue = curValue + c;
}
else {
// ... do something with curValue ...
System.out.println(curValue);
// reset curValue
curValue = "";
}
}
if (curValue.length() > 0) {
// ... do something with curValue ...
System.out.println(curValue);
}
We just iterate over the characters and accumulate them in "curValue" until you hit a dash. Then you process what is in "curValue" and reset it back to a blank string. After iterating all characters you need to process the last value left in "curValue".
I made a java program to count the number of vowels in a string, and I need to use a, or multiple, for loop(s) to do it for a project. The problem is that it does not do anything, or just takes too long, after inputting the string:
import java.util.Scanner;
class Main
{
public static void main(String[] args)
{
Scanner s = new Scanner(System.in);
System.out.print("Enter a string to count the vowels>> ");
String x = s.nextLine();
int numVowels = countVowels(x, "aeiou");
System.out.println(numVowels);
}
static int countVowels(String x, String vowels)
{
int count = 0;
String z = x.toLowerCase();
for (int i = 0; i <= vowels.length() - 1; i++)
{
if (i == vowels.length() - 1)
{
for (int n = z.indexOf(vowels.substring(i)); n != -1; count++)
{
z.replace(vowels.substring(i), "");
}
}
else if (z.indexOf(vowels.substring(i, i + 1)) != -1)
{
for (int n = z.indexOf(vowels.substring(i, i + 1)); n != -1; count++)
{
z.replace(vowels.substring(i, i + 1), "");
}
}
}
return count;
}
}
I have reduced the number of loops, because the original was very confusing. I think the problem is with the nested loops, but I have not yet tried running this on a local compiler, only online IDEs. I've heard that it makes a world of difference for compile times.
It's an infinite loop: you're not doing anything with z if you use only z.replace. Since strings are immutable in Java, you can't change it by only calling a method, you must assign it again:
z = z.replace(...)
I took the liberty of using while-loop instead of for-loop since the idea is to keep looping till find, count and replace all the vowels one by one.
static int countVowels(String x, String vowels) {
int count = 0;
String z = x.toLowerCase();
for (int i = 0; i < vowels.length(); i++) {
String vowel = Character.toString(vowels.charAt(i));
while (z.indexOf(vowel) != -1) {
count++;
z = z.replaceFirst(vowel, "");
}
}
return count;
}
Given two non-negative numbers num1 and num2 represented as strings, return the sum of num1 and num2.
The length of both num1 and num2 is less than 5100.
Both num1 and num2 contain only digits 0-9.
Both num1 and num2 do not contain any leading zeros.
You must not use any built-in BigInteger library or convert the inputs to integer directly.
I tried my solution but it doesn't work. Suggestions?
public class Solution {
public String addStrings(String num1, String num2) {
double multiplier = Math.pow(10, num1.length() - 1);
int sum = 0;
for (int i = 0; i < num1.length(); i++){
sum += ((((int) num1.charAt(i)) - 48) * multiplier);
multiplier /= 10;
}
multiplier = Math.pow(10, num2.length() - 1);
for (int i = 0; i < num2.length(); i++){
sum += ((((int) num2.charAt(i)) - 48) * multiplier);
multiplier /= 10;
}
return "" + sum;
}
}
You must not use any built-in BigInteger library or convert the inputs to integer directly.
Note that you are adding two integers of up to 5100 digits each. That is not that max value, but the max number of digits.
An int (your sum variable) cannot hold values like that. BigInteger can, but you're not allowed to use it.
So, add the numbers like you would on paper: Add last digits, write lower digit of the sum as last digit of result, and carry-over a one if needed. Repeat for second-last digit, third-last digit, etc. until done.
Since the sum will be at least the number of digits of the longest input value, and may be one longer, you should allocate a char[] of length of longest input plus one. When done, construct final string using String(char[] value, int offset, int count), with an offset of 0 or 1 as needed.
The purpose of this question is to add the numbers in the string form. You should not try to convert the strings to integers. The description says the length of the numbers could be up to 5100 digits. So the numbers are simply too big to be stored in integers and doubles. For instance In the following line:
double multiplier = Math.pow(10, num1.length() - 1);
You are trying to store 10^5100 in a double. In IEEE 754 binary floating point standard a double can a store number from ±4.94065645841246544e-324 to ±1.79769313486231570e+308. So your number won't fit. It will instead turn into Infinity. Even if it fits in double it won't be exact and you will encounter some errors in your follow up calculations.
Because the question specifies not to use BigInteger or similar libraries you should try and implement string addition yourself.
This is pretty straightforward just implement the exact algorithm you follow when you add two numbers on paper.
Here is working example of adding two strings without using BigInteger using char array as intermediate container. The point why double can't be used has been explained on #Tempux answer. Here the logic is similar to how adding two numbers on paper works.
public String addStrings(String num1, String num2) {
int carry = 0;
int m = num1.length(), n = num2.length();
int len = m < n ? n : m;
char[] res = new char[len + 1]; // length is maxLen + 1 incase of carry in adding most significant digits
for(int i = 0; i <= len ; i++) {
int a = i < m ? (num1.charAt(m - i - 1) - '0') : 0;
int b = i < n ? (num2.charAt(n - i - 1) - '0') : 0;
res[len - i] = (char)((a + b + carry) % 10 + '0');
carry = (a + b + carry) / 10;
}
return res[0] == '0' ? new String(res, 1, len) : new String(res, 0, len + 1);
}
This snippet is relatively small and precise because here I didn't play with immutable String which is complicated/messy and yield larger code. Also one intuition is - there is no way of getting larger output than max(num1_length, num2_length) + 1 which makes the implementation simple.
You have to addition as you do on paper
you can't use BigInteger and the String Length is 5100, so you can not use int or long for addition.
You have to use simple addition as we do on paper.
class AddString
{
public static void main (String[] args) throws java.lang.Exception
{
String s1 = "98799932345";
String s2 = "99998783456";
//long n1 = Long.parseLong(s1);
//long n2 = Long.parseLong(s2);
System.out.println(addStrings(s1,s2));
//System.out.println(n1+n2);
}
public static String addStrings(String num1, String num2) {
StringBuilder ans = new StringBuilder("");
int n = num1.length();
int m = num2.length();
int carry = 0,sum;
int i, j;
for(i = n-1,j=m-1; i>=0&&j>=0;i--,j--){
int a = Integer.parseInt(""+num1.charAt(i));
int b = Integer.parseInt(""+num2.charAt(j));
//System.out.println(a+" "+b);
sum = carry + a + b;
ans.append(""+(sum%10));
carry = sum/10;
}
if(i>=0){
for(;i>=0;i--){
int a = Integer.parseInt(""+num1.charAt(i));
sum = carry + a;
ans.append(""+(sum%10));
carry = sum/10;
}
}
if(j>=0){
for(;j>=0;j--){
int a = Integer.parseInt(""+num2.charAt(j));
sum = carry + a;
ans.append(""+(sum%10));
carry = sum/10;
}
}
if(carry!=0)ans.append(""+carry);
return ans.reverse().toString();
}
}
You can run the above code and see it works in all cases, this could be written in more compact way, but that would have been difficult to understand for you.
Hope it helps!
you can use this one that is independent of Integer or BigInteger methods
public String addStrings(String num1, String num2) {
int l1 = num1.length();
int l2 = num2.length();
if(l1==0){
return num2;
}
if(l2==0){
return num1;
}
StringBuffer sb = new StringBuffer();
int minLen = Math.min(l1, l2);
int carry = 0;
for(int i=0;i<minLen;i++){
int ind = l1-i-1;
int c1 = num1.charAt(ind)-48;
ind = l2-i-1;
int c2 = num2.charAt(ind)-48;
int add = c1+c2+carry;
carry = add/10;
add = add%10;
sb.append(add);
}
String longer = null;
if(l1<l2){
longer = num2;
}
else if(l1>l2){
longer = num1;
}
if(longer!=null){
int l = longer.length();
for(int i=minLen;i<l;i++){
int c1 = longer.charAt(l-i-1)-48;
int add = c1+carry;
carry = add/10;
add = add%10;
sb.append(add);
}
}
return sb.reverse().toString();
}
The method takes two string inputs representing non-negative integers and returns the sum of the integers as a string. The algorithm works by iterating through the digits of the input strings from right to left, adding each digit and any carryover from the previous addition, and appending the resulting sum to a StringBuilder. Once both input strings have been fully processed, any remaining carryover is appended to the output string. Finally, the string is reversed to produce the correct output order.
Hope this will solve the issue.!
public string AddStrings(string num1, string num2)
{
int i = num1.Length - 1, j = num2.Length - 1, carry = 0;
StringBuilder sb = new StringBuilder();
while (i >= 0 || j >= 0 || carry != 0) {
int x = i >= 0 ? num1[i--] - '0' : 0;
int y = j >= 0 ? num2[j--] - '0' : 0;
int sum = x + y + carry;
sb.Append(sum % 10);
carry = sum / 10;
}
char[] chars = sb.ToString().ToCharArray();
Array.Reverse(chars);
return new string(chars);
}
Previous solutions have excess code. This is all you need.
class ShortStringSolution {
static String add(String num1Str, String num2Str) {
return Long.toString(convert(num1Str) + convert(num2Str));
}
static long convert(String numStr) {
long num = 0;
for(int i = 0; i < numStr.length(); i++) {
num = num * 10 + (numStr.charAt(i) - '0');
}
return num;
}
}
class LongStringSolution {
static String add(String numStr1, String numStr2) {
StringBuilder result = new StringBuilder();
int i = numStr1.length() - 1, j = numStr2.length() - 1, carry = 0;
while(i >= 0 || j >= 0) {
if(i >= 0) {
carry += numStr1.charAt(i--) - '0';
}
if(j >= 0) {
carry += numStr2.charAt(j--) - '0';
}
if(carry > 9) {
result.append(carry - 10);
carry = 1;
} else {
result.append(carry);
carry = 0;
}
}
if(carry > 0) {
result.append(carry);
}
return result.reverse().toString();
}
}
public class Solution {
static String add(String numStr1, String numStr2) {
if(numStr1.length() < 19 && numStr2.length() < 19) {
return ShortStringSolution.add(numStr1, numStr2);
}
return LongStringSolution.add(numStr1, numStr2);
}
}
For the sake of comprehension of the question
your method's name is addition
you are trying to do a power operation but the result is stored in a variable named multiplication...
there is more than one reason why that code doesnt work...
You need to do something like
Integer.parseInt(string)
in order to parse strings to integers
here the oficial doc
I'm trying create a method which returns char type. The condition is this: system takes 9 digits from user input and calculate it. The method converts each char in the nextLine() input and computes the sum then take % 11. If the remainder is 10, method return 'X' and if the remainder is 0 through 9, then the method returns that digit but must be in char type. So far I'm lost at why it will always output '/' and nothing else. Please help me find out the mistake of my algorithms.
public static char getCheckSum(String isbn) {
int sum = 0;
char charSum;
for (int i = 0; i < isbn.length(); i++) {
int[] num = new int[isbn.length()];
num[i] = Character.getNumericValue(i) * (i+1);
sum = sum + num[i];
}
int last = (sum % 11);
if (last == 10){
charSum = (char) 88;
} else {
charSum = (char) (last + 48);
}
return charSum;
//this is the next part where it inserts hyphens just as a reference
public static String formatISBNWithHyphens(String isbn) {
// original isbn: 123456789
// possible new isbn: 1-234-56789-X
char isbn10 = getCheckSum(isbn);
String isbn10Str = isbn + Character.toString(isbn10);
// char[] c = new char[isbn10Str.length()]; *leaving this here for future learning.
String[] cStr = new String[isbn10Str.length()];
String isbnStr = "";
for (int i = 0; i < isbn10Str.length(); i++){
cStr[i] = Character.toString(isbn10Str.charAt(i));
// c[i] = isbn10Str.charAt(i); *leaving this here for future learning.
if (i == 0 || i == 3 || i == 8 ) {
cStr[i] += '-';
}
isbnStr += cStr[i];
}
return isbnStr;
}
// The final outcome is always like this 321654987/ and 3-216-54987-/
it is supposed to be either numbers from 0 to 9 or X if remainder is 10.
Please help. Thanks a bunch.
I think the problem is here
for (int i = 0; i < isbn.length(); i++) {
int[] num = new int[isbn.length()];
num[i] = Character.getNumericValue(i) * (i+1);
sum = sum + num[i];
}
The for cycle returning a result has no relationship with the isbn's content, the result just depends on the isbn string length!
so you can change the code to the following one below
for (int i = 0; i < isbn.length(); i++) {
int[] num = new int[isbn.length()];
num[i] = Character.getNumericValue(isbn.charAt(i));
sum = sum + num[i];
}
the code above returns a result depending on the isbn's content
I'm just having a hard time grasping this concept.
each char has a different ASCII value, so how do i grab the lowest value or the highest value?
and if i passed an empty string to my method for all of this min() would just get thrown an error or would it return a 0?
i wrote a test driver that should pass if my min method returns w as the minimum, which is just a stub method right now, character in that string.
final String PASS = "Pass";
final String FAIL = "Fail";
L05A lab5 = new L05A();
int testNum = 1;
String tst = ""; // test empty string
String result = FAIL;
System.out.println("\nTesting min\n");
tst = "";
char ch = lab5.min(tst);
result = (ch == '!') ? PASS : FAIL;
System.out.println(testNum + ": " + result);
++testNum;
tst = "zyxw"; //would return w?
ch = lab5.min(tst);
result = (ch == 'w') ? PASS : FAIL;
System.out.println(testNum + ": " + result);
++testNum;
So how would i scan that string i pass to return the smallest char?
At first i thought i could use str.charAt(0); but silly me, that just returns the first index of the string, so i'm very confused! Any help would be great to develop this min method
I SHOULD SPECIFY THAT WE ARE NOT USING ANY FORM OF ARRAYS[] ON THIS ASSIGNMENT
UNFORTUNATELY.. :(
It's pretty simple:
Convert the string to a char array using String.toCharArray
Convert the array to a Collection<Character>
Pass the collection to Collections.min and max from java.util.Collections
For example:
String test = "test";
List<Character> strArr = new ArrayList<Character>(test.length());
for (char c : test.toCharArray()) strArr.add(c);
System.out.println(Collections.min(strArr)); // prints "e"
EDIT Ok, so now you say you can't use Arrays, so you just do this instead:
String test = "test";
char[] chars = test.toCharArray();
char max = Character.MIN_VALUE;
char min = Character.MAX_VALUE;
for (int i = 0; i < chars.length; i++) {
char c = chars[i];
max = max > c ? max : c;
min = min < c ? min : c;
}
System.out.println(min);
And, finally, if you can't use an array (like char[]) then you just drop the toCharArray call, and start the loop like this:
for (int i = 0; i < test.length(); i++) {
char c = test.charAt(i);
get char array out of string
iterate over it
define temp int variable assign to 0
compare ASCII of char to temp var and assign temp var to ascii if temp var is smaller/bigger(based on min max value you need from that function)
once the loop is over, you have what you want in that temp var
You should sort the array first:
Arrays.sort(arr);
Then your minimum value will be its first element:
int minimum = arr[0];
Do note that Arrays.sort does sorting in-place and returns nothing.
I expect there is a utility class which will do this for you, but what you could do is call toCharArray on the string, iterate over the array it returns and look for the smallest char (char is effectively a number so comparisons like < > <= >= etc will work on it)
edit:
String foo = "ksbvs";
final char[] chars = foo.toCharArray();
// create a variable to bung the smallest char in
// iterate over the array chars
// compare the current char to the smallest char you have seen so far, update if it's smaller
public class TestCharASCIIValue {
public static void main(String[] args) {
String slogan = "Programming Java Makes me go nutts"; // The String under test
int maxASCII = 0; // As minimum value for a character in ASCII is 0.
int minACSII = 255; // As maximum value for a character in ASCII is 255
int stringLength = slogan.length();
for(int i =0; i < stringLength; i++) {
int tempASCII = slogan.codePointAt(i);
if(tempASCII > maxASCII)
maxASCII = tempASCII;
else if (tempASCII < minACSII)
minACSII = tempASCII;
}
System.out.println("Max : " + maxASCII + " MIN : " + minACSII);
char maxChar = (char)maxASCII;
char minChar = (char) minACSII;
System.out.println("MaxChar : "+maxChar +"\t MinChar : " + minChar);
}
}
OUTPUT :
Max : 118 MIN : 32
MaxChar : v MinChar : (blank space)
EDIT : As per your Query, If you want to test only for max or min valued char then you can use this.
public class TestCharASCIIValue {
public static void main(String[] args) {
String slogan = "Programming Java Makes me go nutts";
char maxChar = (char)getMaxChar(slogan);
char minChar = (char)getMinChar(slogan);
System.out.println("MaxChar : "+maxChar +"\t MinChar : " + minChar);
}
private static int getMaxChar(String testString) {
int maxASCII = 0;
int stringLength = testString.length();
if(stringLength == 0) {
return -1;
}
for(int i =0; i < stringLength; i++) {
int tempASCII = testString.codePointAt(i);
if(tempASCII > maxASCII)
maxASCII = tempASCII;
}
return maxASCII;
}
private static int getMinChar(String testString) {
int minASCII = 255;
int stringLength = testString.length();
if(stringLength == 0) {
return -1;
}
for(int i =0; i < stringLength; i++) {
int tempASCII = testString.codePointAt(i);
if(tempASCII < minASCII)
minASCII = tempASCII;
}
return minASCII;
}
}