I am creating a simple program to convert binary numbers to hex, without the use of the methods provided by Java to do so. I have most of my code already, I'm just having trouble with my "split string" method.
Basically all I am trying to do in this method is
1) Take in a string (binary number)
2) Create an array of strings to hold the "groupings" of numbers
3) Split the binary number into groups of 4 digits (e.g. 10011101 = 1001, 1101)
4) Return the array of groupings
However, when using my method, it always only takes 3 for the first element in my "groupings" array. (e.g. should be "1001", but only putting "100"). What am I doing wrong here?
public String[] splitIntoFours (String toSplit) {
int stringPart = 4;
int arraySize = toSplit.length() / 4;
String[] groupings = new String[arraySize];
for (int iterator = 0; (iterator * stringPart) < toSplit.length(); iterator++){
//If statement to deal with the inital case of the iterator being 0,
//where this algorithm only takes the first 3 numbers instead of a
//sequence of 4 numbers.
int start = iterator * stringPart;
int end = start + stringPart;
if (end > toSplit.length()) {
end = toSplit.length();
}
groupings[iterator] = toSplit.substring(start, end);
}
return groupings;
}
Remember that substring will not return the character at the index denoted by end. It returns end-1.
The Javadoc and extract
public String substring(int beginIndex,
int endIndex)
Returns a new string that is a substring of this string. The substring begins at the specified beginIndex and extends to the character at index endIndex - 1. Thus the length of the substring is endIndex-beginIndex.
Examples:
"hamburger".substring(4, 8) returns "urge"
"smiles".substring(1, 5) returns "mile"
The second parameter (endIndex) in String.substring is exclusive, look closely at the examples in the doc.
Copying this code and running it, it works correctly. So there is no problem. The output, using a String.length dividable through 4, is correct.
Your method works fine, although it throws an error when the size of the number that has to be split is not an multiple of four. This method is a bit more generic:
public static String[] split(String str, int sizeOfGroups) {
int arraySize = str.length() / sizeOfGroups;
String[] groupings = new String[arraySize+1];
int num1, num2;
for (int i = 0; i * sizeOfGroups < str.length(); i++) {
num1 = i * sizeOfGroups + sizeOfGroups;
num2 = i * sizeOfGroups;
if ((num1 >= str.length())) {
groupings[i] = str.substring(num2, str.length());
} else {
groupings[i] = str.substring(num2, num1);
}
}
return groupings;
}
Related
I have to implement the .length method from String class "by hand" and I have no idea and hope you can help somehow.
No other methods or functions are allowed, than:
String.charAt()
String.substring()
String.isEmpty()
Bit-operations &,|, &&,||, <<, >>,>>>, !=, ==
Arithmetic operations
for and while Loop
recursion
if else statement
self created methods (int,String,char,boolean etc.)
self-created Arrays. (no Methods of them)
static void manual_length2(String length) {
//example String length = "Hello" = 5 letters.
int counter = 0;
int i = 0;
char g = ' ';
while(i <= 4 ) { /*4 is the number i already know */
g = length.charAt(i);
counter += 1;
length.substring(1);
++i;
}
System.out.println(counter);
Console: 5
This was my approach, but I'm stuck in the while statement's condition to terminate.
With the example "Hello" i already know that this word has 5 letters, but it needs to fit for all inputs. So i don't know how to express to border-value of the while statement.
Another approach is by recursion, but also, i ask myself how can i express the limit of the recursion.
How can i express:
.... lengthMethod1(String length, int ???) {
if(n == 0) {
return length.charAt(0);
}
else {
return ???? lengthMethod1(length, n - 1);
}
You can loop until the String is empty while removing the first character on each iteration.
static int manual_length(String str) {
int len = 0;
while(!str.isEmpty()){
++len;
str = str.substring(1);
}
return len;
}
This can be converted to a tail-recursive method as well.
static int manual_length(String str) {
return str.isEmpty() ? 0 : 1 + manual_length(str.substring(1));
}
Another approach is by recursion, but also, i ask myself how can i
express the limit of the recursion. How can i express:
Yes, you can do recursively like this:
static int manual_length(String str, int len) {
return str.isEmpty() ? len : manual_length(str.substring(1), len + 1);
}
You use an accumulator variable (i.e., len), that you increment, while removing a char from the string (i.e., str.substring(1)). When you reach the end (i.e., str.isEmpty()) you return the accumulator.
I was recently going through a question in codehub and I was unable to solve this query. Can anyone help me how can this be solved?
You are given a string S of length N. You can select and reverse any substring of S of any length. You are allowed to perform this operation many number of times.
Determine maximum number of mismatches by performing operation.
Mismatch(S) is defined as number of corresponding positions were characters are different in S and reverse(S). For example : S = abab, reverse(S) = baba. Number of mismatches = 4. S= abca. Number of mismatches = 2.
Pseudo code :
static int solve( String S, int n)
{
//To do
}
Will be helpful if some one can explain once the code is done how this can be interpreted more easily and approached to solve.
I recently encountered the same question in one of the competency tests, I don't know about above solution, but my implementation below in python works for above problem
import itertools
def maximum_mismatches(s,n):
if len(set(s)) == 1:
return 0
maxc = 0
for str_c in set(itertools.permutations(s,n)):
rev_str = str_c[::-1]
counter = 0
for i in range(n):
if str_c[i] != rev_str[i]:
counter += 1
if maxc < counter:
maxc = counter
return maxc
I have tested for multiple test cases, it is working
Calculate the frequency of each character in the string and then take the difference of frequency of each character. See the code example in Java. It returns the max mismatch of characters of a string & it's reverse, given that a substring in the original string can be reversed any number of times.
Examples: 1. cantaaaa (answer = 6), 2. cbbaa (answer = 4), 3. aaaaabbbbccdd (answer = 12)
public static int maxMismatch(String str){
if(str == null || str.length() <= 1) return 0;
int freq[] = new int[26];
for(int i = 0; i < str.length(); i++){
freq[str.charAt(i) - 97]++;
}
int diff = 0;
for(int i = 0; i < freq.length; i++){
diff = Math.abs(freq[i] - diff);
}
return str.length() - diff;
}
import itertools as it
def mismatch(S,n):
max =0
for x in set(it.permutations(S[::-1],n)):
cnt = 0
for i in range(n):
if x[i]!=S[i]:
cnt+=1
if cnt > max:
max=cnt
return max
#include <bits/stdc++.h>
using namespace std;
int max_mismatch(string s)
{
unordered_map<char,int> fmap;
for(auto &ch:s)
fmap[ch]++;
vector<int> tempV;
for(auto &[_,f]:fmap)
tempV.push_back(f);
sort(tempV.begin(),tempV.end(),greater<int>());
vector<int> freq(tempV.size());
int diff=0,left=0,right=freq.size()-1;
bool leftinsert=true;
for(auto f:tempV)
{
if(leftinsert)
freq[left++]=f;
else
freq[right--]=f;
leftinsert^=1;
}
/*for(auto &val:freq)
cout<<val<<" ";
cout<<endl; */
left=0;right=freq.size()-1;
for(int i=0;i<s.size()/2;i++)
{
if(left==right)
break;
if(!(--freq[left])) left++;
if(!(--freq[right])) right--;
diff+=2;
}
return diff;
}
int main()
{
string s="aatacanaa";
cout<<max_mismatch(s);
}
First a function to calculate the mismatch score, using this spec:
Mismatch(S) is defined as number of corresponding positions were characters are different in S and reverse(S). For example : S = abab, reverse(S) = baba. Number of mismatches = 4. S= abca. Number of mismatches = 2.
We don't need to actually reverse the string. Just compare the first character with the last, then the second with the second last, etc. I find it straightforward to use two index variables for something like this:
int mismatches(String s) {
int result = 0;
int i = 0;
int j = s.length() - 1;
while (j >= 0) {
if (s.charAt(i) != s.charAt(j)) result++;
i++;
j--;
}
return result;
}
And here are some tests to increase our confidence:
#Test
public void test_mismatches() {
assertEquals(0, mismatches(""));
assertEquals(0, mismatches("a"));
assertEquals(0, mismatches("aa"));
assertEquals(2, mismatches("ab"));
assertEquals(0, mismatches("aaa"));
assertEquals(2, mismatches("aab"));
assertEquals(2, mismatches("abc"));
assertEquals(0, mismatches("aaaa"));
assertEquals(2, mismatches("aaab"));
assertEquals(2, mismatches("aaba"));
assertEquals(4, mismatches("abcd"));
}
Now let's find the max mismatch. Here is the spec:
You are given a string S of length N. You can select and reverse any
substring of S of any length. You are allowed to perform this
operation many number of times.
Determine maximum number of mismatches by performing operation.
This is unclear and has typos. It is lazily written and if it was client work, I would be asking for a clarification. I've been burned in the past by working from unclear specs, and building something that the client didn't intend.
I think the use of the word "reverse" is a misnomer. I think it is to help hint at a solution for calculating the mismatch. The spec should be:
You are given a string. Determine maximum number of mismatches from any substring. For clarity, the original string is a valid substring of itself.
With this revised spec, we can just use a nested for loop to traverse the search space:
int maxMismatches(String s) {
int result = 0;
for (int i = 0; i < s.length(); i++)
for (int j = s.length(); j > i; j--) {
int mismatch = mismatches(s.substring(i, j));
if (mismatch > result)
result = mismatch;
}
return result;
}
And some tests:
#Test
public void test_max_mismatches() {
assertEquals(0, maxMismatches(""));
assertEquals(0, maxMismatches("a"));
assertEquals(0, maxMismatches("aa"));
assertEquals(2, maxMismatches("ab"));
assertEquals(2, maxMismatches("aba"));
assertEquals(4, maxMismatches("aabbaa"));
assertEquals(6, maxMismatches("aaabcda"));
}
There is a gap in this set of tests. Some of the test strings require truncating the start to find the max. Some require truncating the end, but none require truncating both the start and end.
Both functions have obvious optimisations but they reduce clarity in a scenario where I don't think performance is important.
Here you could first reverse the giving string and then just iterate through the giving string and compare character at each index in both the giving string and reversed string and if there is a mismatch increase the counter.
Check the below code
public static void main(String args[])throws IOException {
String s = "abab";
System.out.println(solve(s,s.length()));
}
static int solve( String s, int n)
{
//this can also be used to reverse string
//String reversed = new StringBuilder(s).reverse().toString();
String revStr = Stream.of(s)
.map(word->new StringBuilder(word).reverse())
.collect(Collectors.joining(" "));
int counter = 0;
for(int loop=0; loop < n; loop++){
if(s.charAt(loop)!=revStr.charAt(loop)){
++counter;
}
}
return counter;
}
I'm writing a method for my CS151 class called countSevens(n). It Returns count how many digits are 7 in the given number n. This is what I have so far but I'm doing something wrong that I can't figure out.
public int countSevens(int n){
int count = 0;
String strI = Integer.toString(n);
for (int i = 0; i < strI.length(); i++){
if(strI.substring(i).equals("7")){
count++;
}
}
return count;
}
You can do it with java streams
public int countSevens(int n) {
return (int) String.valueOf(n).chars().filter(ch -> ch == '7').count();
}
(int) - cast to an int type, in this particular case it safe to cast long to int, because we can't get a conversation error. In other cases it's better to use Math.toIntExact(long)
String.valueOf(n) - convert to string
chars() - return stream of chars
filter(ch -> ch == '7') - filter all chars that equals to 7
count() - returns the count of elements in this stream
strI.substring(i)
Will return the part of string from i-character to the end.
Use strI.charAt(i) instead
From the definition of String.substring(int):
Returns a string that is a substring of this string. The substring begins with the character at the specified index and extends to the end of this string.
So this will only count the last instance of a 7 in your number, and only if it's the last digit in the number.
Instead, try this:
if(strI.substring(i, i+1).equals("7"))
Or, since you're dealing with ints, you can avoid using strings altogether. n % 10 will get you the last digit, and n /= 10 will bump the entire number right by one digit. That should be enough to get you started on doing this without Strings.
To count the number of 7s in an integer:
int counter = 0;
int number = 237123;
String str_number = String.valueOf(number);
for(char c : str_number.toCharArray()){
if(c == '7'){
counter++;
}
}
You can just use simple arithmetics:
public static int countSevens(int i) {
int count = 0;
for (i = i < 0 ? -i : i; i != 0; count += i % 10 == 7 ? 1 : 0, i /= 10);
return count;
}
But who can read this? Not many, so here is a cleaner solution, applying the same logic:
public static int countSevens(int i) {
int count = 0;
// ignore negative numbers
i = Math.abs(i);
while(i != 0) {
// if last digit is a 7
if(i % 10 == 7) {
// then increase the counter
count++;
}
// remove the last digit
i /= 10;
}
return count;
}
is there a function in java that works like SUBSTRING function but for integers. Like for example the user's input is 456789, I want to break it into two part and put them into different variable. and divide them. for example,
user's input : 456789
the first 3 numbers will be in variable A.
the last 3 numbers will be in variable B.
pass = A/B;
can someone help me how can I do this,
thanks.
Use integer division and the modulus operator:
int input = 456789;
int a = input / 1000;
int b = input % 1000;
Here is a mathematical based implementation for positive and negative integers (probably can be optimized):
public static void main(String[] args) {
System.out.println(substring(2, 0, 1)); // prints "2"
System.out.println(substring(2523, 2, 2)); // prints "23"
System.out.println(substring(-1000, 0, 2)); // prints "-1"
System.out.println(substring(-1234, 0, 4)); // prints "-123"
System.out.println(substring(-1010, 2, 1)); // prints "0"
System.out.println(substring(-10034, 3, 2)); // prints "3"
System.out.println(substring(-10034, 2, 4)); // prints "34"
}
public static int substring(int input, int startingPoint, int length) {
if (startingPoint < 0 || length < 1 || startingPoint + length > size(input)) {
throw new IndexOutOfBoundsException();
}
if (input < 0 && startingPoint == 0 && length < 2) {
throw new IndexOutOfBoundsException("'-' can not be returned without a digit");
}
input /= (int) Math.pow(10, size(input) - length - startingPoint); // shift from end by division
input = input % (int) Math.pow(10, length); // shift from start by division remainder
if (input < 0 && startingPoint > 0) {
input = Math.abs(input); // update sign for negative input
}
return input;
}
private static int size(int input) {
int size = 1;
while (input / 10 != 0) {
size++;
input /= 10;
}
return input < 0 ? ++size : size; // '-'sign is a part of size
}
Splitting a "number" is not what you want to do. You want to split the NUMERAL, which is the string representing a quantity (number). You can split the numeral just like any other literal (string): don't parse the user's input and use substring. If you want to make sure the literal is an actual numeral, parse it to see if an exception is thrown. If not, you have a numeral. But don't hold on to the integers, keep the strings instead.
Here you go:
You give the method a number, start, and end indexes.
public static void main(String[] args) {
System.out.println(getPartOfInt(93934934, 3, 7));`
}
public static int getPartOfInt(int number, int start, int end){
Integer i = new Integer(number);
char[] chars = i.toString().toCharArray();
String str = "";
for(int j = start; j < end && j < chars.length; j++){
str += chars[j];
}
return Integer.parseInt(str);
}
OR:
public static int getPartOfInt(int number, int start, int end){
String str = new Integer(number).toString();
return Integer.parseInt(str.substring(start, Math.min(end, str.length())));
}
You could also first convert the number to String, like so:
int num = 456789;
String strNum = String.valueOf(num);
String part1 = strNum.substring(0, strNum.length() / 2 - 1);
String part2 = strNum.substring(strNum.length() / 2);
Then, you could convert it back to int, like so:
int part1Num = Integer.parseInt(part1);
int part2Num = Integer.parseInt(part2);
Now you can do all the arithmetic you want with those two int's.
#DeanLeitersdorf Here's the function ( #clcto s solution)
int subinteger(int input, int from, int size)
{
while (input > pow(10, size + from) - 1)
input /= 10;
return input % (int)pow(10, size);
}
This is a c++ solution but i hope that you can convert it to Java easily
I am trying to match a string to another such that at least 3 characters match between the two. My string should be of exact length 4, all capitals, 3 letters and 1 digit between 0 and 10 (excluding 0 and 10). eg : RM5Z
How can I do that in java in the most simplified form?
To check form of your string you can use this ^(?=[A-Z]*[1-9][A-Z]*$).{4}$ regex
^.{4}$ will ensure length 4
^(?=[A-Z]*[1-9][A-Z]*$) will accept only strings that contains digit in range 1-9 that can be surrounded with letters A-Z
Not sure if this is the way you want to check your Strings, let me know
static boolean testStrings(String a, String b) {
if (isValid(a) && isValid(b)) {
for (int i = 0; i < 4; i++) {
a = a.replaceFirst(String.valueOf(b.charAt(i)), "");
}
return a.length() <= (4 - 3);
}else
return false;
}
static boolean isValid(String s) {
return s.matches("^(?=[A-Z]*[1-9][A-Z]*$).{4}$");
}
If you want to know whether two strings of length 4 have three characters in common and you know all the chars are in a restricted range, then you can just intersect bitsets and count the bits thus:
public static boolean haveNCharsInCommon(String a, String b, int n) {
BitSet charsInA = charsIn(a);
BitSet charsInB = charsIn(b);
charsInA.and(charsInB);
return charsInA.cardinality() >= n;
}
private BitSet charsIn(String s) {
BitSet bs = new BitSet();
for (int i = 0, n = s.length(); i < n; ++i) {
bs.set(s.charAt(i);
}
return bs;
}
If the strings could contain arbitrary codepoints you would probably want to use a sparse vector instead of a bitset.