I'm new to java and still learning, so keep that in mind. I'm trying to write a program where a user can type in a keyword and it'll convert it to numbers and put it in an array. My problem is the array needs to keep repeating the int's.
My code is:
String keyword=inputdata.nextLine();
int[] key = new int[keyword.length()];
for (int k = 0; k < keyword.length(); ++k)
{
if (keyword.charAt(k) >= 'a' && keyword.charAt(k) <= 'z')
{
key[k]= (int)keyword.charAt(k) - (int)'a';
}
}
Right now if I try to get any key[i] higher than the keyword.length it throws an outofbounds error. I need it to to be infinte.
So basically, if keyword.length() were 3 I need to be able to see if key[2] is the same as key[5] and key[8] and so on.
Thanks for your help!
Well, it's easiest to fix your code with a bit of refactoring first. Extract all uses of keyword.charAt(k) to a local variable:
for (int k = 0; k < keyword.length(); ++k)
{
char c = keyword.charAt(k);
if (c >= 'a' && c <= 'z')
{
key[k] = c'a';
}
}
Then we can fix the issue with the % operator:
// I assume you actually want a different upper bound?
for (int k = 0; k < keyword.length(); ++k)
{
char c = keyword.charAt(k % keyword.length());
if (c >= 'a' && c <= 'z')
{
key[k] = c - 'a';
}
}
That's assuming you actually make key longer than keyword - and you probably want to change the upper bound of the loop too. For example:
int[] key = new int[1000]; // Or whatever
for (int k = 0; k < key.length; ++k)
{
char c = keyword.charAt(k % keyword.length());
if (c >= 'a' && c <= 'z')
{
key[k] = c - 'a';
}
}
Related
I was doing practice algorithms problems HackerRank website and I submitted my code firstly in C language but I got some Test Cases incorrect. I thought my logic was right so I ported my code to Java and I passed all my Test Cases.
Link to the problem definition:
https://www.hackerrank.com/challenges/caesar-cipher-1
Here is my code in C:
int main(){
int n;
scanf("%d", &n);
char* s = (char *)malloc(n * sizeof(char));
scanf("%s", s);
int k;
scanf("%d", &k);
k = k % 26;
for(int i = 0; i < n; i++){
if(s[i] >= 65 && s[i] <= 90){
s[i] += k;
if(s[i] > 90){
s[i] = s[i] - 90 + 64;
}
}
if(s[i] >= 97 && s[i] <= 122){
s[i] += k;
if(s[i] > 122){
s[i] = s[i] - 122 + 96;
}
}
}
printf("%s", s);
return 0;
}
And here is my code in Java:
public class Solution {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
String str = br.readLine();
int K = Integer.parseInt(br.readLine());
K %= 26;
for(int i = 0; i < N; i++){
char c = str.charAt(i);
if(c >= 65 && c <= 90){
c += K;
if(c > 90){
c = (char)(c - 90 + 64);
}
}
if(c >= 97 && c <= 122){
c += K;
if(c > 122){
c = (char)(c - 122 + 96);
}
}
System.out.print(c);
}
}
}
Both my solutions are passing Sample Test Cases and logic is all the same. I can't understand why it is showing W/A in C in some Test Cases.
P.S. This is practice problem solution and not a live contest solution.
C strings are terminated with a special '\0' character appended to their end. So an actual string is always 1 character longer than the visible text.
You are not allocating memory for the input string null terminator:
Replace
char* s = (char *)malloc(n * sizeof(char));
with
char* s = malloc(n * sizeof(char) + 1);
or even
char* s = malloc(n + 1);
as sizeof(char) is guaranteed to be 1.
In addition there would be a problem with these lines:
if(s[i] >= 97 && s[i] <= 122){
s[i] += k;
s[i] might be 122 and k might be very well greater than 5. As s[i] is most likely signed char type, and it might overflow past the value of 127, which is the maximum for signed char. And signed integer overflow has an undefined behavior.
This one is working fine.
int main(){
int n;
scanf("%d",&n);
char* s = (char *)malloc(10240 * sizeof(char));
scanf("%s",s);
int k;
scanf("%d",&k);
for(int i = 0; i < n; i++){
if(s[i] >= 65 && s[i] <= 90){
s[i] = (s[i]-'A'+k)%26 +'A';
}
if(s[i] >= 97 && s[i] <= 122){
s[i] = (s[i]-'a'+k)%26 +'a';
}
}
printf("%s", s);
return 0;
}
Just updated contents of if blocks and malloc size.
Hi I am trying to convert from lower to uppercase. I know they are other easier ways to do this, but I want something else. It seems that the program prints out the users input more than once, so I am almost 100% sure it's the loop. But I can't find where the problem is.
String a = input.nextLine();
String c = "";
int b = a.length();
for (int i = 0 ; i < b; i++)
{
if (a.charAt(i) >= 97 && a.charAt(i) <= 122)
{
c = c + a;
System.out.println(c.toUpperCase());
}
}
Actually your code logic wasn't totally right, I mean why would you add the content of a to c? Doesn't make sense, and you excluded the letters a and z in your if.
String a = input.nextLine();
String c = "";
int b = a.length();
for (int i = 0; i < b; i++) {
if (a.charAt(i) >= 97 && a.charAt(i) <= 122) {
c = c + a.charAt(i);
}
}
System.out.println(c.toUpperCase());
You're printing c in each iteration of the loop where the if is entered instead of just once, after it ends.
Why bother going through the loop at all?
String a = input.nextLine();
System.out.println( a.toUpperCase();
will do what you want
If you want to invert the characters:
StringBuffer sb = new StringBuffer(a);
for ( int i=0; i < sb.length(); i++ ) {
char c = sb.charAt(i);
if ( c.isLower() ) {
sb.setCharAt(i,c.toUpper());
} else if ( c.isUpper() ) {
sb.setCharAt(i,c.toLower());
}
}
String result = sb.toString();
This solution should work:
for (int i = 0 ; i < b; i++)
{
if (a.charAt(i) > 97 && a.charAt(i) < 122)
{
a = a.toUpperCase();
}
}
System.out.println(a);
Given an input, I'm trying to write a program to find the minimum base that can be associated with that number. For example the minimum base associated with 385 is base-9 (as it needs to have a base that supports the digit 8 which is its highest value digit). Similarly, the minimum base associated with B95 is base-12, since it uses 0 -9 and A and B.
This is my code
public static int findBase(String str){
int max = 0;
char c;
for (int i = 0; i <str.length() ; i++) {
c = str.toUpperCase().charAt(i);
if (Character.isDigit(c) && c > max) {
max = c;
}else if (Character.isLetter(c)) {
max = 10 + (c - 'A');
}
}
return max + 1;
}
The problem is that the function is returning random values.For example for the value 385 it returns 56. What am I doing wrong?
The problem is that you're using the unicode value of the character when it's a digit.
Instead of:
max = c;
... you should use:
max = c - '0';
Also note that Character.isLetter returns true for all unicode letters, including Arabic letters and letters from other alphabets, that have much higher unicode codepoint values; likewise for Character.isDigit
In your case, you're only capable of handling Latin characters from the ASCII character set, so to be safe it's better to check for that specifically.
And you're not checking correctly for the maximum value (you're comparing the unicode codepoint to the max, not the converted value)
int v = 0;
if (c >= '0' && c <= '9') {
v = c - '0';
} else if (c >= 'A' && c <= 'Z') {
v = 10 + (c - 'A');
}
if (v > max) {
max = v;
}
Full program:
public static int findBase(String str) {
int max = 0;
str = str.toUpperCase();
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
int v = 0;
if (c >= '0' && c <= '9') {
v = c - '0';
} else if (c >= 'A' && c <= 'Z') {
v = 10 + (c - 'A');
}
if (v > max) {
max = v;
}
}
return max + 1;
}
Take following code as base:
for (int i = 0; i < 26; i++)
{
alphabet[i] = (char) ('A'+ i );
}
My question is: -
If 'A' Changes to 'X' how can we achieve the alphabet to reset from the start?
For example XYZABC
Whenever you have something that should "wrap around", have a look at the modulo operator. The basic idea is: you don't want to count from i=0 to 26, but e.g. from i=23 to 49, but only add the modulo-26 value to it.
Instead of starting to count at 23 (which would be kind of 'X' - 'A'), you can directly integrate this offset into your loop:
for (int i = 0; i < 26; i++)
{
alphabet[i] = (char) ('A' + ('X' - 'A' + i) % 26);
}
'A' is the base, 'X' - 'A' builds that offset where you add i to, and then take the modulo of 26 (as the alphabet has 26 characters), and then add that to your 'A' again.
You can just insert an if statement:
char startChar = 'X';
for (int i = 0; i < 26; i++) {
char ch = (char) (startChar + i);
if (ch > 'Z') {
ch -= 26;
}
alphabet[i] = ch;
}
(EDITED)
My problem statement: write a method that will encode the String passed to the method by adding 13 letters to each character in the String. If the letter after adding 13 exceeds 'z' then "wrap around" the alphabet. Then return the encoded String.
encodeString("hello") → "uryyb"
encodeString("pie") → "cvr"
encodeString("book") → "obbx"
this is what I have so far :
public static String encodeString (String input) {
String output;
for (int i = 0; i < input.length(); i++) {
char c = input.charAt(i);
if (c >= 'a' && c <= 'm')
c += 13;
else if (c >= 'n' && c <= 'z')
c -= 13;
output= (" " + (c));
}
return output;
}
now I know that I have to create a counter so that the method will continue to loop until it reaches the length of the string passed...and I know that if the charAt(index) is less than the character 'n' that I add 13 and if it is greater then I subtract 13. when I put it all together though I just get so confused and just get a bunch of compiling errors like Type mismatch: cannot convert from int to String.
note straightforward explanations/answers would be much appreciated...
***so now my problem is that it keeps telling me my output variable may not have been initialized
This code is not the most performatic but works good with Upper and Lower characters.
hElLo → uRyYb
pIe → cVr
bOoK → oBbX
private static String encodeString(String string) {
char[] ret = new char[string.length()];
for (int i = 0; i < string.length(); i++) {
ret[i] = rot13(string.charAt(i));
}
return String.valueOf(ret);
}
public static char rot13(char c) {
if (Character.isLetter(c)) {
if (Character.compare(Character.toLowerCase(c), 'a') >= 0
&& Character.compare(Character.toLowerCase(c), 'm') <= 0)
return c += 13;
else
return c -= 13;
}
return c;
}
You have to initialize your output variable as an empty String. Furthermore you are always replacing the contents of the output variable with the last char you've just encoded. So you have to add every char to the output with += instead of =.
So here is the fixed solution:
public static String encodeString(String input) {
String output = ""; // initialize as empty String
for (int i = 0; i < input.length(); i++) {
char c = input.charAt(i);
if (c >= 'a' && c <= 'm') {
c += 13;
} else if (c >= 'n' && c <= 'z') {
c -= 13;
}
output += " " + c; // add all chars to the String instead of replacing the whole String with "="!
}
return output;
}
I beautified your code a bit, so everybody can see what it really does.
Use an IDE!