My professor have given me a challenging homework, where the idea is to rewrite all the methods in the String classes without using String, StringBuilder, and Wrapper classes. This is for Intro to Java class. I already have some methods done but having a hard time with some other ones. This is for the main class only with no creation of any string inside.
What I have: a "data" as a char[] data for my "MyOwnString" object.
CompareTo method:
public int compareTo(MyOwnString rhs){
if (this.data == rhs.data){
return 0;
} else if (this.data > rhs.data){
return 1;
}
else {
return -1;
}
}
This one shows an error. My guess is that the rhs needs to be declare before being able to compare to any string being assigned to a MyOwnString object.
Since there is a compareTo method and a compareToIgnoreCase, then I would have to add a line to ignore the comparsion?
Update:
This is the code I went with for the compareTo method by creating own method using length of the array.
public int compareTo(MyOwnString cts){
int word1 = data.length;
int word2 = cts.length();
int result = 0;
for (int i=0; i<word1; i++){
for (int j=0;j<word2; j++){
if(word1 == word2){
result = 0;
}
else if (word1 > word2){
result = 1;
}
else {
result = -1;
}
}
}
return result;
}
Since you are not allowed to use String.compareTo()
and since java doesn't support > for your custom objects or char[] for that matter (e.g doesn't support operator overloading) you have to do it programmatically.
In other words you have the two char arrays and you have to loop through all the characters. You compare the first two characters from each of the char arrays (there you can use > or <) if they are == you compare the second two characters and so on.. till you find two characters that break the tie - you can then break your for loop and return the result as -1, 1. If they are tied on every character you return 0.
If you want to implement equals you could just call compareTo and optimize it a bit by checking the lengths of the strings. If they are different then of course the strings are not equal
Update: I am not sure if you ran your code above - try to compile your code and run it before you move forward. I believe it won't even compile.
Here is, I believe, a correct unchecked version. I could have mixed the -1 and 1s as always..
public int compareTo(MyOwnString cts){
int word1Length = ((MyOwnString)this).data.length;
int word2Length = cts.data.length;
for (int i=0; i < Math.min(word1Length,word2Length); i++){
if(this.data[i] == cts.data[i]){
continue;
}
else if (this.data[i] > cts.cts[i]){
return -1;
}
else if (this.data[i] < cts.cts[i]) {
return 1;
}
}
if (word1Length == word2Length){
return 0;
}
else if(word1Length < word2Length){
return 1;
}
else {
return -1;
}
}
public boolean equals(MyOwnString cts){
int word1Length = ((MyOwnString)this).data.length;
int word2Length = cts.data.length;
if (word1Length != word2Length){
return false;
}
else { // if they are equal
int comparison = this.compareTo(cts);
if (comparison==0){
return true;
}
else {
return false;
}
}
}
You can't compare char[] objects with the > operator, since it's not defined on them. You'll have to iterate over the char[] arrays and compare the characters yourself.
BTW, it's very easy to cheat in this assignment, since the code of the String class is available online.
Related
Basically what I want to do is to check on each element in an array of int, if all elements are of the same value.
I create int array as below to pass to the method for comparing each array element, it return boolean true even tough the elements are not all the same values.
Int[] denominator = {3,3,4,3};
boolean compare;
compare = bruteforce(denominator);
public static boolean bruteforce(int[] input) {
int compare =0;
int count =0;
for (int i = 0; i < input.length; i++) {
compare = input[i];
while(count<input.length){
if(input[i+1]==compare){
return true;
}
i++;
count++;
}//end while
}//end for
return false;
}//end method
I suppose the method above will loop for and keep compare for each element of the array.
When I print out the output, it showed that it only loop once, the return the boolean as true.
I really lost the clue what could be wrong in my code.
Perhaps I just overlook of some silly mistakes.
Try,
Integer[] array = {12,12,12,12};
Set<Integer> set = new HashSet<Integer>(Arrays.asList(array));
System.out.println(set.size()==1?"Contents of Array are Same":"Contents of Array are NOT same");
Explanation:
Add the array to a set and check the size os set , if it is 1 the contents are same else not.
You only need one loop and should return false as quickly as possible where applicable (i.e. when you encounter an element that doesn't match the first).
You also need to account for the edge cases that the input array is null or has one element.
Try something like this, which I minimally adapted from the code you provided...
public class BruteForceTest {
public static boolean bruteforce(int[] input) {
// NOTE: Cover the edge cases that the input array is null or has one element.
if (input == null || input.length == 1)
return true; // NOTE: Returning true for null is debatable, but I leave that to you.
int compare = input[0]; // NOTE: Compare to the first element of the input array.
// NOTE: Check from the second element through the end of the input array.
for (int i = 1; i < input.length; i++) {
if (input[i] != compare)
return false;
}
return true;
}
public static void main(String[] args) {
int[] denominator = {3,3,4,3};
boolean compare = bruteforce(denominator);
// FORNOW: console output to see where the first check landed
System.out.print("{3,3,4,3}:\t");
if (compare)
System.out.println("Yup!");
else
System.out.println("Nope!");
// NOTE: a second array to check - that we expect to return true
int[] denominator2 = {2,2};
boolean compare2 = bruteforce(denominator2);
System.out.print("{2,2}:\t\t");
if (compare2)
System.out.println("Yup!");
else
System.out.println("Nope!");
/*
* NOTE: edge cases to account for as noted below
*/
// array with one element
int[] denominator3 = {2};
System.out.print("{2}:\t\t");
if (bruteforce(denominator3))
System.out.println("Yup!");
else
System.out.println("Nope!");
// null array
System.out.print("null:\t\t");
if (bruteforce(null))
System.out.println("Yup!");
else
System.out.println("Nope!");
}
}
...and outputs:
{3,3,4,3}: Nope!
{2,2}: Yup!
{2}: Yup!
null: Yup!
If an array elements are equal you only need to compare the first element with the rest so a better solution to your problem is the following:
public static boolean bruteforce(int[] input) {
for(int i = 1; i < input.length; i++) {
if(input[0] != input[i]) return false;
}
return true;
}
You don't need more than one loop for this trivial algorithm. hope this helps.
If all elements are the same value, why not use only one for loop to test the next value in the array? If it is not, return false.
If you want to check if all elements are of same value then you can do it in a simpler way,
int arr = {3,4,5,6};
int value = arr[0];
flag notEqual = false;
for(int i=1;i < arr.length; i++){
if(!arr[i] == value){
notEqual = true;
break;
}
}
if(notEqual){
System.out.println("All values not same");
}else{
System.out.println("All values same);
}
Right now, you are not checking if "all the elements are of the same value". You are ending the function and returning true whenever (the first time) two elements are equal to each other.
Why not set the boolean value to true and return false whenever you have two elements that are not equal to each other? That way you can keep most of what you have already.
if(input[i+1]!=compare) return false;
public class Answer {
public static void main(String[] args)
{
boolean compare = false;
int count = 0;
int[] denominator = { 3, 3, 4, 3 };
for (int i = 0; i < denominator.length; i++)
{
if(denominator[0] != denominator[i])
{
count++;
}
}
if(count > 0)
{
compare = false;
} else
{
compare = true;
}
System.out.println(compare);
}
}
One mistake that I noticed right of the bat was that you declared your array as Int[], which is not a java keyword it is in fact int[]. This code checks your array and returns false if the array possesses values that are not equal to each other. If the array possesses values that are equal to each other the program returns true.
If you're interested in testing array equality (as opposed to writing out this test yourself), then you can use Arrays.equals(theArray, theOtherArray).
So I am trying to figure out if two strings when combined together are a substring of a permutation of another string.
I have what I believe to be a working solution but it is failing some of the JUnit test cases and I dont have access to the ones that it is failing on.
here is my code with one test case
String a="tommarvoloriddle";
String b="lord";
String c="voldemort";
String b= b+c;
char[] w= a.toCharArray();
char[] k= b.toCharArray();
Arrays.sort(k);
Arrays.sort(w);
pw.println(isPermuation(w,k)?"YES":"NO");
static boolean isPermuation(char[] w, char[] k)
{
boolean found=false;
for(int i=0; i<k.length; i++)
{
for(int j=i; j<w.length; j++)
{
if(k[i]==w[j])
{
j=w.length;
found=true;
}
else
found=false;
}
}
return found;
}
any help getting this to always produce the correct answer would be awesome and help making it more efficient would be great too
What you have is not a working solution. However, you don't explain why you thought it might be, so it's hard to figure out what you intended. I will point out that your code updates found unconditionally for each inner loop, so isPermutation() will always return the result of the last comparison (which is certainly not what you want).
You did the right thing in sorting the two arrays in the first place -- this is a classic step which should allow you to efficiently evaluate them in one pass. But then, instead of a single pass, you use a nested loop -- what did you intend here?
A single pass implementation might be something like:
static boolean isPermutation(char[] w, char[] k) {
int k_idx=0;
for(w_idx=0; w_idx < w.length; ++w_idx) {
if(k_idx == k.length)
return true; // all characters in k are present in w
if( w[w_idx] > k[k_idx] )
return false; // found character in k not present in w
if( w[w_idx] == k[k_idx] )
++k_idx; // character from k corresponds to character from w
}
// any remaining characters in k are not present in w
return k_idx == k.length;
}
So we are only interested in whether the two combined strings are a subset of a permutation of another string, meaning that the lengths can in fact differ. So let's say we have:
String a = "tommarvoloriddle";
String b = "lord";
String c = "voldemort";
char[] master = a.ToCharArray();
char[] combined = (b + c).ToCharArray();
Arrays.Sort(master);
Arrays.Sort(combined);
System.out.println(IsPermutation(master, combined) ? "YES" : "NO");
Then our method is:
static boolean IsPermutation(char[] masterString, char[] combinedString)
{
int combinedStringIndex = 0;
int charsFound = 0;
int result = 0;
for (int i = 0; i < masterString.Length; ++i) {
result = combinedString[combinedStringIndex].CompareTo(masterString[i]);
if (result == 0) {
charsFound++;
combinedStringIndex++;
}
else if (result < 0) {
return false;
}
}
return (charsFound == combinedString.Length);
}
What the above method does: it starts comparing characters of the two strings. If we have a mismatch, that is, the character at the current masterString index does not match the character at the current combinedString index, then we simply look at the next character of masterString and see if that matches. At the end, we tally the total number of characters matched from our combinedString, and, if they are equal to the total number of characters in combinedString (its length), then we have established that it is indeed a permutation of masterString. If at any point, the current character in masterString is numerically greater than the current character in combinedString then it means that we will never be able to match the current character, so we give up. Hope that helps.
If two Strings are a permuation of the other you should be able to do this
public static boolean isPermuted(Strign s1, String s2) {
if (s1.length() != s2.length()) return false;
char[] chars1 = s1.toCharArray();
char[] chars2 = s2.toCharArray();
Arrays.sort(chars1);
Arrays.sort(chars2);
return Arrays.equals(chars1, chars2);
}
This means that when sorted the characters are the same, in the same number.
Give a two-dimensional array T with base type String and some string str (which can be treated like an array of type String) I want to check if T contains certain parts str as its entries. I tried this:
int indeksck = str.indexOf("C");
while(k<T.length){
if(T[k][2] == str.substring(indeksck+1)){
if(T[k][1] == str.substring(6, indeksck)){
int ile_o = Integer.parseInt(T[k][0]);
T[k][0]= Integer.toString(ile_o+1);
T[k][3] = T[k][3]+"X"+str.substring(1,6);
k = T.length+1;
} else {
k++;
}
} else {
k++;
if(k==T.length){
k = 0;
while(k<T.length){
if(T[k][0]==null){
T[k][0] = Integer.toString(1);
T[k][1] = str.substring(6,indeksck);
T[k][2] = str.substring(indeksck+1);
T[k][3] = str.substring(1,6);
k = T.length+1;
} else {
k++;
}
}
}
}
}
The problem is that the first part of my code is being ignored (even when condition should be satisfied). I would appreciate and suggestions on solving this problem.
You cannot use == to do string compare. Try:
if(T[k][2].equals(str.substring(indeksck+1))) {
== operator in Java is used for reference comparison. To check equivalence for objects (so also for strings) you need to use equals() method.
so i've already made a class method that searches for a specific word, but (like most times i find myself on here!) i've had a brain malfunction and can't figure out how to modify it to do what i need. here's what i've got so far:
private static int findFourLetterWord(String[] strings, String key) {
for (int i = 0; i < strings.length; i++)
if (strings[i].equals(key))
return i;
return -1;
}
so this searches an array for 'key' and returns with it's position if it is found. what i'm trying to get it to do is search an array of strings for the first 4 letter word it encounters and return with that word. i would change the first return to be System.out.println(strings[i]); i believe, but i'm not sure how to make it search for the first 4 letter word it finds. tried using a bunch of convoluted substrings but that didn't work. any advice or guidance would be great. thank you in advance.
Your current method is close; you just need to change the condition in the for-loop to check for a length of 4 using String#length() rather than equality to a key argument.
private static String findFourLetterWord(String[] strings) {
for (String str : strings) {
if (str.length() == 4) {
return str;
}
}
return null;
}
Never forget to consult the JavaDocs when you find yourself unsure of what methods are available for your convenience.
Am I understanding your question right?
private static String findFourLetterWord(String[] strings) {
for (int i = 0; i < strings.length; i++)
if (strings[i].length()==4)
return strings[i];
return null;
}
Use substring function to get the first 4 character of the key and string as below:
private static int FindFourLetterWord(String[] strings, String key) {
//Assuming key length is 4 or more
String keyWithFourChars = key.substring(0,4);
for (int i = 0; i < strings.length; i++){
if(strings[i].length() > 3){
if (strings[i].substring(0,4).eqauls(keyWithFourChars)){
return i;
}
}
}
return -1;
}
If you want to just look for 4 chars string, then simply check the length as below:
In this case, you don't need to pass key as parameter.
private static int FindFourLetterWord(String[] strings) {
for (int i = 0; i < strings.length; i++){
if(strings[i].length() == 4){
return i;
}
}
return -1;
}
I need to chek where the char c index is on string , and if the char c is'nt there - return -1.
public class Find {
private String _st;
int i;
public Find(String st) {
_st = st;
}
public int whatIstheIndex(char c) {
for (i=0;i<_st.length();i++)
if (_st.charAt(i) == c) {
return i;
} else {
return -1;
}
return i;
}
}
I'm getting always -1. Why? Is the last return i; unnecessary?
Remove the else clause, it's returning -1 if the first character in the string isn't correct.
You would then also need to change the return statement at the end of the method.
Why don't you just use the built-in indexOf method? That would be a lot easier and quicker than looping through the string and testing each and every character.
But if you have to use this method for some strange reason, get rid of your else clause, because it makes the function return -1 every time the character tested is not matched.
Here is an alternative solution which also works.
public int whatIstheIndex(char c) {
int result = -1;
for (int i = 0; i < _st.length(); i++) {
if (_st.charAt(i) == c) {
result = i;
}
}
return result;
}
It's just a different way of thinking about the problem. I suppose it's slightly "worse" because it adds an extra line of code, but I hope you see how/why this works.
Your code should be like this:
public int whatIstheIndex(char c) {
for (int i = 0; i < _st.length(); i++)
if (_st.charAt(i) == c) {
return i;
}
return -1;
}
Hope this helps!
Why not use String.indexOf(int) method.
public int whatIstheIndex (char c) {
return _st.indexOf(c);
}
Else, return a -1 only after the loop finishes:
public int whatIstheIndex (char c) {
for (i=0;i<_st.length();i++)
if (_st.charAt(i) == c ) {
return i;
}
}
return -1;
}
What's happening is that it's looking at the first character, and if that doesn't match, it immediately returns -1 (and hence, doesn't continue looping through the chars until it finds the right one).
You need to return -1 only if you have finished the for loop and have not found the character. So it needs to be:
public int whatIstheIndex(char c) {
for (i = 0; i < _st.length(); i++) {
if (_st.charAt(i) == c) {
return i;
}
}
return -1;
}
You are always returning after looking at the first character. Your test doesn't look at other characters. A debugger would show you this. The last return i is only called if the length is 0.
Your current implementation will only ever return one of two values, 0, or -1. 0 is returned when the first index is that which the character resides, or -1 if its not found there. Remove the else clause and return -1 after you've finished the for loop to indicate that you've exhaustively searched all indexes, and found no answer.