Finding sequences of characters, whichever's first - java

I wrote a code that finds four different sequences of characters.
ATG is always at the start and TAG, TGA or TAA are the "stop" sequences.
The number of characters in between START and STOP sequences should by a multiple of 3.
For example in the following String: ACCATGCCCTAGTTT my program returns ATGCCCTAG.
And in this string: AAATGCCTAGTTAA the program returns ATGCCTAGTTAA, because the number of characters between ATG and TGA is not a multiple of three, so it looks for the next "stop" sequence, which is TAA in this case.
Here's the code:
public class TagFinder {
public String findProtein(String dna) {
String fpL = dna.toLowerCase();
int start = fpL.indexOf("atg");
int stop = fpL.indexOf("tag", start+3);
int stop2 = fpL.indexOf("tga", start+3);
int stop3 = fpL.indexOf("taa", start+3);
if (start == -1) {
return "";
}
if ((stop - start) % 3 == 0) {
return fpL.substring(start, stop+3);
}
if ((stop2 - start) % 3 == 0) {
return fpL.substring(start, stop2+3);
}
if ((stop3 - start) % 3 == 0) {
return fpL.substring(start, stop3+3);
}
else {
return "";
}
}
However, In the following String "ATTATGCCCTAATAG", the code will first find ATGCCCTAATAG, even though TAA is the first "stop" sequence in the string and the number of chars between ATG and TAA is 3.
How can I write this program, so that whichever "STOP" sequence appears first in the string and is n3 away from the start sequence is returned.
Thank you.

Regular expressions will do.
String input = "ACCATGCCCTAGTTT";
String expected = "ATGCCCTAG";
Pattern pattern = Pattern.compile("(ATG)(.{3})*?(TAG|TGA|TAA)",
Pattern.CASE_INSENSITIVE);
Matcher m = pattern.matcher(input);
while (m.find()) {
System.out.printf("[%d] %s%n", m.start(), m.group());
}
In the above the start position is not necessarily a multiple of 3. If the start position must be a multiple of 3, then it would easiest to make groups of 3 letters and a separator.
input = input.replaceAll(".{3}", "$0,");
Pattern pattern = Pattern.compile("(ATG,)(.{4})*?(TAG|TGA|TAA),",
Pattern.CASE_INSENSITIVE);
Matcher m = pattern.matcher(input);
while (m.find()) {
System.out.printf("[%d] %s%n", m.start() * 3 / 4, m.group().replace(",", ""));
}

You need to determine the minimum of all stop tags, so I'd write something like this:
[...]
int minStop = MAXINT;
if ((stop - start) % 3 == 0 && minStop > stop) {
minStop = stop;
}
if ((stop2 - start) % 3 == 0 && minStop > stop2) {
minStop = stop2;
}
if ((stop3 - start) % 3 == 0 && minStop > stop3) {
minStop = stop3;
}
if (minStop < MAXINT) {
return fpL.substring(start, minStop+3);
} else {
[...]
}

From
if ((stop - start) % 3 == 0) {
return fpL.substring(start, stop+3);
}
It first finds TAG and the return statement is called. If you really want to find the first stop point, add some comaprison logic between stop, stop2 and stop3 to find which is the smallest index. Then do the % 3 check for each and return from the first one that is ok, or the whole string if there is not a valid case. Also how about using a regular expression for this problem ? Something in the lines of (ATG)\w{3}(TAG|TGA|TAA).

The following code uses a list of any search words, then selects the minimum matched index.
public String findProtein(String dna) {
String fpL = dna.toLowerCase();
int start = fpL.indexOf("atg");
List<String> searchWords = new ArrayList<>();
searchWords.add("tag");
searchWords.add("tga");
searchWords.add("taa");
int start = fpL.indexOf("atg");
try{
int startIndex = searchWords.stream().mapToInt(word -> fpL.indexOf(word, 3 + start)).filter(idx -> idx >= 0 && 0 == idx % 3)
.min().getAsInt();
return dna.substring(start, startIndex + 3);
} catch(NoSuchElementException ex) {
return "";
}
}

The reason the code finds "TAG" first is because the way you've written your code:
Your first if statement checks for "TAG". If it finds one, it returns the string between "ATG" and "TAG" and terminates.
What you need to do is create a min variable and store the value of the found terminator codon in this min (after checking it's really min). NOT using returnin the if statements that search for terminator codons. and returning the min + 3 only after the three if statements executed and determined the real minimum distance from "TAG".
Hope it was useful.

Related

How do I check if the preceding letter of the word that I am looking for in a string exist? Recursion

I am currently creating a java program that counts the number of occurrences of a specific word in a string using recursion, however, if the preceding letter is an 'a', the count won't be incremented. I cannot find a way to check the preceding letter before the first letter of the word I am looking for. I tried using indexOf then subtracting one to check the preceding letter, but it won't work.
Here's my working function at the moment:
//The value of text is abrichbbarichacrich
//While the value of find is rich
//Expected output should be 2
static int Count(String text, String find) {
if (text.length() == 0 || text.length() < find.length()) {
return 0;
}
if (text.contains(find)) {
return 1 + Count(text.replaceFirst(find, ""), find);
}
return 0;
}
Here's my second version, but it gives me a StringIndexOutOfBoundsException and the output should be 2, but instead it gives me an output of 3.
if (text.length() == 0 || text.length() < find.length()) {
return 0;
}
if (text.contains(find)) {
int index = text.indexOf(find) - 1;
if (text.charAt(index) == 'a')
return Count(text.replaceFirst(find, ""), find);
return 1 + Count(text.replaceFirst(find, ""), find);
}
Any help would be appreciated :)
Correct if else condition .replaceFirst() method returns the updated string.We have to update the string.
static int Count(String text, String find) {
if (text.length() == 0 || text.length() < find.length()) {
return 0;
}
if (text.contains(find)) {
int index = text.indexOf(find) - 1;
text=text.replaceFirst(find, "");
if (index!=-1&&text.charAt(index) != 'a'){
return 1+Count(text,find);
}
else
return Count(text,find);
}
return 0;
}
Just working the answer out in pseudocode, here's how I'd approach the problem.
Define a helper function as follows:
countHelper(string text, string find, bool previousWasNotA) =
if (length of text < length of find) {
0
} else {
let prefixEqualsFind = if (previousWasNotA and find is a prefix of text) {
0
} else {
1
}
in
prefixEqualsFind + countHelper(text without first character, find, first character of text != 'a')
}
count(string text, string find) = countHelper(text, find, true)
The idea here is that countHelper(text, find, previousWasNotA) returns the number of occurences of find in text, not counting any occurences where find is directly preceded by an a, and not counting an occurence of find at the very beginning of text if previousWasNotA is false.
In Java, this look like
static int countHelper(String text, String find, bool previousWasNotA) {
if (text.length() < find.length()) {
return 0;
} else {
const int prefixEqualsEnd = previousWasNotA && text.startsWith(find) ? 1 : 0;
return prefixEqualsEnd + countHelper(text.substring(1), find, text.charAt(0) != 'a');
}
}
static int count(String text, String find) {
return countHelper(text, find, true);
}
Note that this doesn't work for the case of find = "". But in that case, it's not clear the problem even has an answer at all, since we can put infinitely many ""s together to make a single "" and hence infinitely many ""s are contained in any string at all.
Also note that this is not an asymptotically optimal algorithm. For that, you'll want to use the KMP algorithm.

JAVA How to check whether a string contains " / " three times or not [duplicate]

How can I count the number of times a particular string occurs in another string. For example, this is what I am trying to do in Javascript:
var temp = "This is a string.";
alert(temp.count("is")); //should output '2'
The g in the regular expression (short for global) says to search the whole string rather than just find the first occurrence. This matches is twice:
var temp = "This is a string.";
var count = (temp.match(/is/g) || []).length;
console.log(count);
And, if there are no matches, it returns 0:
var temp = "Hello World!";
var count = (temp.match(/is/g) || []).length;
console.log(count);
/** Function that count occurrences of a substring in a string;
* #param {String} string The string
* #param {String} subString The sub string to search for
* #param {Boolean} [allowOverlapping] Optional. (Default:false)
*
* #author Vitim.us https://gist.github.com/victornpb/7736865
* #see Unit Test https://jsfiddle.net/Victornpb/5axuh96u/
* #see https://stackoverflow.com/a/7924240/938822
*/
function occurrences(string, subString, allowOverlapping) {
string += "";
subString += "";
if (subString.length <= 0) return (string.length + 1);
var n = 0,
pos = 0,
step = allowOverlapping ? 1 : subString.length;
while (true) {
pos = string.indexOf(subString, pos);
if (pos >= 0) {
++n;
pos += step;
} else break;
}
return n;
}
Usage
occurrences("foofoofoo", "bar"); //0
occurrences("foofoofoo", "foo"); //3
occurrences("foofoofoo", "foofoo"); //1
allowOverlapping
occurrences("foofoofoo", "foofoo", true); //2
Matches:
foofoofoo
1 `----´
2 `----´
Unit Test
https://jsfiddle.net/Victornpb/5axuh96u/
Benchmark
I've made a benchmark test and my function is more then 10 times
faster then the regexp match function posted by gumbo. In my test
string is 25 chars length. with 2 occurences of the character 'o'. I
executed 1 000 000 times in Safari.
Safari 5.1
Benchmark> Total time execution: 5617 ms (regexp)
Benchmark> Total time execution: 881 ms (my function 6.4x faster)
Firefox 4
Benchmark> Total time execution: 8547 ms (Rexexp)
Benchmark> Total time execution: 634 ms (my function 13.5x faster)
Edit: changes I've made
cached substring length
added type-casting to string.
added optional 'allowOverlapping' parameter
fixed correct output for "" empty substring case.
Gist
https://gist.github.com/victornpb/7736865
function countInstances(string, word) {
return string.split(word).length - 1;
}
console.log(countInstances("This is a string", "is"))
You can try this:
var theString = "This is a string.";
console.log(theString.split("is").length - 1);
My solution:
var temp = "This is a string.";
function countOccurrences(str, value) {
var regExp = new RegExp(value, "gi");
return (str.match(regExp) || []).length;
}
console.log(countOccurrences(temp, 'is'));
You can use match to define such function:
String.prototype.count = function(search) {
var m = this.match(new RegExp(search.toString().replace(/(?=[.\\+*?[^\]$(){}\|])/g, "\\"), "g"));
return m ? m.length:0;
}
Just code-golfing Rebecca Chernoff's solution :-)
alert(("This is a string.".match(/is/g) || []).length);
The non-regex version:
var string = 'This is a string',
searchFor = 'is',
count = 0,
pos = string.indexOf(searchFor);
while (pos > -1) {
++count;
pos = string.indexOf(searchFor, ++pos);
}
console.log(count); // 2
String.prototype.Count = function (find) {
return this.split(find).length - 1;
}
console.log("This is a string.".Count("is"));
This will return 2.
Here is the fastest function!
Why is it faster?
Doesn't check char by char (with 1 exception)
Uses a while and increments 1 var (the char count var) vs. a for loop checking the length and incrementing 2 vars (usually var i and a var with the char count)
Uses WAY less vars
Doesn't use regex!
Uses an (hopefully) highly optimized function
All operations are as combined as they can be, avoiding slowdowns due to multiple operations
String.prototype.timesCharExist=function(c){var t=0,l=0,c=(c+'')[0];while(l=this.indexOf(c,l)+1)++t;return t};
Here is a slower and more readable version:
String.prototype.timesCharExist = function ( chr ) {
var total = 0, last_location = 0, single_char = ( chr + '' )[0];
while( last_location = this.indexOf( single_char, last_location ) + 1 )
{
total = total + 1;
}
return total;
};
This one is slower because of the counter, long var names and misuse of 1 var.
To use it, you simply do this:
'The char "a" only shows up twice'.timesCharExist('a');
Edit: (2013/12/16)
DON'T use with Opera 12.16 or older! it will take almost 2.5x more than the regex solution!
On chrome, this solution will take between 14ms and 20ms for 1,000,000 characters.
The regex solution takes 11-14ms for the same amount.
Using a function (outside String.prototype) will take about 10-13ms.
Here is the code used:
String.prototype.timesCharExist=function(c){var t=0,l=0,c=(c+'')[0];while(l=this.indexOf(c,l)+1)++t;return t};
var x=Array(100001).join('1234567890');
console.time('proto');x.timesCharExist('1');console.timeEnd('proto');
console.time('regex');x.match(/1/g).length;console.timeEnd('regex');
var timesCharExist=function(x,c){var t=0,l=0,c=(c+'')[0];while(l=x.indexOf(c,l)+1)++t;return t;};
console.time('func');timesCharExist(x,'1');console.timeEnd('func');
The result of all the solutions should be 100,000!
Note: if you want this function to count more than 1 char, change where is c=(c+'')[0] into c=c+''
var temp = "This is a string.";
console.log((temp.match(new RegExp("is", "g")) || []).length);
A simple way would be to split the string on the required word, the word for which we want to calculate the number of occurences, and subtract 1 from the number of parts:
function checkOccurences(string, word) {
return string.split(word).length - 1;
}
const text="Let us see. see above, see below, see forward, see backward, see left, see right until we will be right";
const count=countOccurences(text,"see "); // 2
I think the purpose for regex is much different from indexOf.
indexOf simply find the occurance of a certain string while in regex you can use wildcards like [A-Z] which means it will find any capital character in the word without stating the actual character.
Example:
var index = "This is a string".indexOf("is");
console.log(index);
var length = "This is a string".match(/[a-z]/g).length;
// where [a-z] is a regex wildcard expression thats why its slower
console.log(length);
Super duper old, but I needed to do something like this today and only thought to check SO afterwards. Works pretty fast for me.
String.prototype.count = function(substr,start,overlap) {
overlap = overlap || false;
start = start || 0;
var count = 0,
offset = overlap ? 1 : substr.length;
while((start = this.indexOf(substr, start) + offset) !== (offset - 1))
++count;
return count;
};
var myString = "This is a string.";
var foundAtPosition = 0;
var Count = 0;
while (foundAtPosition != -1)
{
foundAtPosition = myString.indexOf("is",foundAtPosition);
if (foundAtPosition != -1)
{
Count++;
foundAtPosition++;
}
}
document.write("There are " + Count + " occurrences of the word IS");
Refer :- count a substring appears in the string for step by step explanation.
Building upon #Vittim.us answer above. I like the control his method gives me, making it easy to extend, but I needed to add case insensitivity and limit matches to whole words with support for punctuation. (e.g. "bath" is in "take a bath." but not "bathing")
The punctuation regex came from: https://stackoverflow.com/a/25575009/497745 (How can I strip all punctuation from a string in JavaScript using regex?)
function keywordOccurrences(string, subString, allowOverlapping, caseInsensitive, wholeWord)
{
string += "";
subString += "";
if (subString.length <= 0) return (string.length + 1); //deal with empty strings
if(caseInsensitive)
{
string = string.toLowerCase();
subString = subString.toLowerCase();
}
var n = 0,
pos = 0,
step = allowOverlapping ? 1 : subString.length,
stringLength = string.length,
subStringLength = subString.length;
while (true)
{
pos = string.indexOf(subString, pos);
if (pos >= 0)
{
var matchPos = pos;
pos += step; //slide forward the position pointer no matter what
if(wholeWord) //only whole word matches are desired
{
if(matchPos > 0) //if the string is not at the very beginning we need to check if the previous character is whitespace
{
if(!/[\s\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&\(\)*+,\-.\/:;<=>?#\[\]^_`{|}~]/.test(string[matchPos - 1])) //ignore punctuation
{
continue; //then this is not a match
}
}
var matchEnd = matchPos + subStringLength;
if(matchEnd < stringLength - 1)
{
if (!/[\s\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&\(\)*+,\-.\/:;<=>?#\[\]^_`{|}~]/.test(string[matchEnd])) //ignore punctuation
{
continue; //then this is not a match
}
}
}
++n;
} else break;
}
return n;
}
Please feel free to modify and refactor this answer if you spot bugs or improvements.
For anyone that finds this thread in the future, note that the accepted answer will not always return the correct value if you generalize it, since it will choke on regex operators like $ and .. Here's a better version, that can handle any needle:
function occurrences (haystack, needle) {
var _needle = needle
.replace(/\[/g, '\\[')
.replace(/\]/g, '\\]')
return (
haystack.match(new RegExp('[' + _needle + ']', 'g')) || []
).length
}
Try it
<?php
$str = "33,33,56,89,56,56";
echo substr_count($str, '56');
?>
<script type="text/javascript">
var temp = "33,33,56,89,56,56";
var count = temp.match(/56/g);
alert(count.length);
</script>
Simple version without regex:
var temp = "This is a string.";
var count = (temp.split('is').length - 1);
alert(count);
No one will ever see this, but it's good to bring back recursion and arrow functions once in a while (pun gloriously intended)
String.prototype.occurrencesOf = function(s, i) {
return (n => (n === -1) ? 0 : 1 + this.occurrencesOf(s, n + 1))(this.indexOf(s, (i || 0)));
};
function substrCount( str, x ) {
let count = -1, pos = 0;
do {
pos = str.indexOf( x, pos ) + 1;
count++;
} while( pos > 0 );
return count;
}
ES2020 offers a new MatchAll which might be of use in this particular context.
Here we create a new RegExp, please ensure you pass 'g' into the function.
Convert the result using Array.from and count the length, which returns 2 as per the original requestor's desired output.
let strToCheck = RegExp('is', 'g')
let matchesReg = "This is a string.".matchAll(strToCheck)
console.log(Array.from(matchesReg).length) // 2
Now this is a very old thread i've come across but as many have pushed their answer's, here is mine in a hope to help someone with this simple code.
var search_value = "This is a dummy sentence!";
var letter = 'a'; /*Can take any letter, have put in a var if anyone wants to use this variable dynamically*/
letter = letter && "string" === typeof letter ? letter : "";
var count;
for (var i = count = 0; i < search_value.length; count += (search_value[i++] == letter));
console.log(count);
I'm not sure if it is the fastest solution but i preferred it for simplicity and for not using regex (i just don't like using them!)
You could try this
let count = s.length - s.replace(/is/g, "").length;
We can use the js split function, and it's length minus 1 will be the number of occurrences.
var temp = "This is a string.";
alert(temp.split('is').length-1);
Here is my solution. I hope it would help someone
const countOccurence = (string, char) => {
const chars = string.match(new RegExp(char, 'g')).length
return chars;
}
var countInstances = function(body, target) {
var globalcounter = 0;
var concatstring = '';
for(var i=0,j=target.length;i<body.length;i++){
concatstring = body.substring(i-1,j);
if(concatstring === target){
globalcounter += 1;
concatstring = '';
}
}
return globalcounter;
};
console.log( countInstances('abcabc', 'abc') ); // ==> 2
console.log( countInstances('ababa', 'aba') ); // ==> 2
console.log( countInstances('aaabbb', 'ab') ); // ==> 1
substr_count translated to Javascript from php
Locutus (Package that translates Php to JS)
substr_count (official page, code copied below)
function substr_count (haystack, needle, offset, length) {
// eslint-disable-line camelcase
// discuss at: https://locutus.io/php/substr_count/
// original by: Kevin van Zonneveld (https://kvz.io)
// bugfixed by: Onno Marsman (https://twitter.com/onnomarsman)
// improved by: Brett Zamir (https://brett-zamir.me)
// improved by: Thomas
// example 1: substr_count('Kevin van Zonneveld', 'e')
// returns 1: 3
// example 2: substr_count('Kevin van Zonneveld', 'K', 1)
// returns 2: 0
// example 3: substr_count('Kevin van Zonneveld', 'Z', 0, 10)
// returns 3: false
var cnt = 0
haystack += ''
needle += ''
if (isNaN(offset)) {
offset = 0
}
if (isNaN(length)) {
length = 0
}
if (needle.length === 0) {
return false
}
offset--
while ((offset = haystack.indexOf(needle, offset + 1)) !== -1) {
if (length > 0 && (offset + needle.length) > length) {
return false
}
cnt++
}
return cnt
}
Check out Locutus's Translation Of Php's substr_count function
The parameters:
ustring: the superset string
countChar: the substring
A function to count substring occurrence in JavaScript:
function subStringCount(ustring, countChar){
var correspCount = 0;
var corresp = false;
var amount = 0;
var prevChar = null;
for(var i=0; i!=ustring.length; i++){
if(ustring.charAt(i) == countChar.charAt(0) && corresp == false){
corresp = true;
correspCount += 1;
if(correspCount == countChar.length){
amount+=1;
corresp = false;
correspCount = 0;
}
prevChar = 1;
}
else if(ustring.charAt(i) == countChar.charAt(prevChar) && corresp == true){
correspCount += 1;
if(correspCount == countChar.length){
amount+=1;
corresp = false;
correspCount = 0;
prevChar = null;
}else{
prevChar += 1 ;
}
}else{
corresp = false;
correspCount = 0;
}
}
return amount;
}
console.log(subStringCount('Hello World, Hello World', 'll'));
var str = 'stackoverflow';
var arr = Array.from(str);
console.log(arr);
for (let a = 0; a <= arr.length; a++) {
var temp = arr[a];
var c = 0;
for (let b = 0; b <= arr.length; b++) {
if (temp === arr[b]) {
c++;
}
}
console.log(`the ${arr[a]} is counted for ${c}`)
}

Removing Consecutive Characters in each Iteration shows Unexpected error

How to remove Consecutive Characters at each Iteration..
Below is the screenshot that explains the question with more details
MySolution
Initially I checked whether there are any Consecutive characters.
If yes,Then,remove all the consecutive characters and when there are no consecutive characters add the remaining characters to another String.
If no Consecutive Characters just simply increment it.
public static void print(){
String s1="aabcccdee"; I have taken a sample test case
String s2="";
for(int i=0;i<s1.length();){
if(s1.charAt(i)==s1.charAt(i+1)){
while(s1.charAt(i)==s1.charAt(i+1)){
i++;
}
for(int j=i+1;j<s1.length();j++){
s2=s2+s1.charAt(j);
}
s1=s2;
}
else
i++;
}
System.out.println(s1);
}
Output Shown
An infinite Loop
Expected Output for the give sample is
bd
Can Anyone guide me how to correct?
You can simply use String::replaceFirts with this regex (.)\1+ which means matche any charater (.) which followed by itself \1 one or more time + with empty.
In case you want to replace first by first you have to check the input, if after each iteration still contain more than one consecutive characters or not, in this case you can use Pattern and Matcher like this :
String[] strings = {"aabcccdee", "abbabba", "abbd "};
for (String str : strings) {
Pattern pattern = Pattern.compile("([a-z])\\1");
// While the input contain more than one consecutive char make a replace
while (pattern.matcher(str).find()) {
// Note : use replaceFirst instead of replaceAll
str = str.replaceFirst("(.)\\1+", "");
}
System.out.println(str);
}
Outputs
aabcccdee -> bd
abbabba -> a
abbd -> ad
Update
I had misread the question. The intent is to also remove the consecutive characters after each replacement. The below code does that.
private static String removeDoubles(String str) {
int s = -1;
for (int i = 1; i < str.length(); i++) {
// If the current character is the same as the previous one,
// remember its start position, but only if it is not set yet
// (its value is -1)
if (str.charAt(i) == str.charAt(i - 1)) {
if (s == -1) {
s = i - 1;
}
}
else if (s != -1) {
// If the current char is not equal to the previous one,
// we have found our end position. Cut the characters away
// from the string.
str = str.substring(0, s) + str.substring(i);
// Reset i. Notice that we don't have to loop from 0 on,
// instead we can start from our last replacement position.
i = s - 1;
// Finally reset our start position
s = -1;
}
}
if (s != -1) {
// Check the last portion
str = str.substring(0, s);
}
return str;
}
Note that this is almost 10 times faster than YCF_L's answer.
Original post
You are almost there, but you don't have to use multiple for loops. You just need one loop, because whether to remove characters from the string only depends on subsequent characters; we don't need to count anything.
Try this:
private static String removeDoubles(String s) {
boolean rem = false;
String n = "";
for (int i = 0; i < s.length() - 1; i++) {
// First, if the current char equals the next char, don't add the
// character to the new string and set 'rem' to true, which is used
// to remove the last character of the sequence of the same
// characters.
if (s.charAt(i) == s.charAt(i + 1)) {
rem = true;
}
// If this is the last character of a sequence of 'doubles', then
// reset 'rem' to false.
else if (rem) {
rem = false;
}
// Else add the current character to the new string
else {
n += s.charAt(i);
}
}
// We haven't checked the last character yet. Let's add it to the string
// if 'rem' is false.
if (!rem) {
n += s.charAt(s.length() - 1);
}
return n;
}
Note that this code is on average more than three times faster than regular expressions.
Try something like this:
public static void print() {
String s1 = "abcccbd"; // I have taken a sample test case
String s2 = "";
while (!s1.equals(s2)) {
s2 = s1;
s1 = s1.replaceAll("(.)\\1+", "");
}
System.out.println(s1);
}
consider this easier to understand code
String s1="aabcccdee";
while (true) {
rvpoint:
for (int x = 0; x < s1.length() -1; x++)
{
char c = s1.charAt(x);
if (c == s1.charAt(x+ 1)) {
s1 = s1.replace(String.valueOf(c), "");
continue rvpoint; // keep looping if a replacement was made
}
}
break; // break out of outer loop, if replacement not found
}
System.out.println(s1);
note
This will only work for the first iteration, put into a method and keep calling until the sizes do not change

Using recursion to add 0 after every even digit

Hello guys,
I would like to share with you my problem. I am practicing recursive methods and i have noticed somewhere one exercise. The exercise is about making the recursive method which adds a 0 to every even digit. If someone has some idea, it would be great if you share here.
the code would be something like this :
public static String adding0AfterEvenNumber(int number) {
String s = String.valueOf(number);
String result;
if (number < 10 && number % 2 == 0) {
return s + 0;
}
}
I am missing the main part of the code but i really do not have an idea how to create it. Thanks in advance
consider this code (comments in line)
// somewhere to store the result
static StringBuilder result = new StringBuilder();
public static void main(String [] args) {
// starting string
String s = "1234567";
// or as
//String s = Integer.toString(1234567);
// call with full string
recurse (s);
// print result
System.out.println("result : " + result.toString());
}
private static void recurse(String s) {
// take first char and add to result
String c = s.substring(0,1);
result.append(c);
// see if even, note no error checking for is a number
if (Integer.parseInt(c) % 2 == 0) {
result.append("0");
}
// then if still has content then strip off first char and call again
if (s.length() > 1)
recurse(s.substring(1));
}
output
result : 1203405607
You would recurse something like this:
public static String adding0AfterEvenNumber(int number) {
return ((number >= 10) ? adding0AfterEvenNumber(number / 10) : "") + String.valueOf(number % 10) + ((number % 2 == 0) ? "0" : "");
}
Try it here.
<script src="//repl.it/embed/JDEV/1.js"></script>
The first part is the terminal condition, appending nothing if there is a single digit number, else calling the recursion after removing the last digit:
(number > 10) ? adding0AfterEvenNumber(number / 10) : "")
The second part appends a zero to the last digit, if even:
String.valueOf(number % 10) + ((number % 2 == 0) ? "0" : "")
I understand that even digits are those digits with an even value not in an even position. The following function should return you a string with the value, although you could return an integer if you shift the head value as many digits as the tail has.
public String add0onEven(int number, int initPos, int endPos) {
if (initPos == endPos - 1) {
int digit = (number / (int) Math.pow(10, initPos)) % 10;
if (digit % 2 == 1) {
return digit + "0";
} else {
return "" + digit;
}
} else if (endPos - initPos < 1) {
return "";
} else {
int sepIdx = (endPos - initPos) / 2 + initPos;
String tail = add0onEven(number, initPos, sepIdx);
String head = add0onEven(number, sepIdx, endPos);
return head + tail;
}
}
You can call the method like this:
add0onEven(1234567, 0, 7)
The output obtained for this invocation:
10230450670
I believe this solution to be better than the substring ones for its lower impact on memory (No need to create a new string on each substring invocation). Besides, it follows a Divide and Conquer approach that suits better to recursivity.

Finding Balanced Parenthesis Involving Math

I've tried to solve this question for the past couple of hours and I just don't understand it. I know there must be a sort of mathematical calculation to calculate this but I don't know how to exactly calculate it. I know this code does not make sense because I'm completely lost, I would appreciate any hints or help for this to help me get closer to the solution.
I asked my professor and he told me a hint about it being similar to a permutation/combination using alphabet such as 26^3 for 3 different combinations but this did not help me much.
What I know:
There are 796 characters for the input given in the string and I must find ALL possible ways that 796 characters can be in a balanced parenthesis form.
Since it must start with '(' and end with ')' there must be 2 brackets for each case. So it can be '()()(xc)(cvs)'. Thus that means the mathematical calculation must involve 2*(something) per char(s) since it has to be balanced.
I need to use the remainder(%) operator to recursively find every case but how do I do that when I take a char in not an int?
What I don't know:
How will I analyze each case? Won't that take a long time or a lot of code without a simple formula to calculate the input?
Would I need a lot of if-statements or recursion?
Question:
Let Σ = {), (}. Let L ⊆ Σ* be the set of strings of correctly balanced parentheses. For example, (())() is in L and (()))( is not in L. Formally, L is defined recursively as follows.
ε ∈ L
A string x ≠ ε is in L if and only if x is of the form (y)z, where y and z are in L.
n is a specific 3 digit number between 0 and 999.
Compute f(n) mod 997
Some facts you might find useful: if n1, n2 is a member of N(natural number) then,
(n1 x n2) mod 997 and
(n1 + n2) mod 997
n = 796 (this is specific for me and this will be the given input in this case)
So I must "compute f(796) mod 997 = ?" using a program. In this case I will simply use java for this question.
Code:
import java.util.*;
public class findBrackets
{
public static void main(String[] args)
{
String n;
int answer = 0;
Scanner input = new Scanner(System.in);
System.out.println("Input String");
n = input.nextLine();
// probably wrong because a string can start as x(d))c(()...
for(int i = 0; i < n; i++)
{
if(n[i] != '(' || n[i] != ')' || n[i] != null || n[i] != " ") {
answer = 2 * (Integer.parseInt(n[i]); // how can i calculate if its a char
// i have to use mod % operator somewhere but I don't know where?
}
}
System.out.println("f(796) mod 997 = " + answer);
}
}
You might find the following fact useful: the number of strings of n pairs of balanced parentheses is given by the nth Catalan number and its exact value is
(2n)! / (n! (n + 1)!)
You should be able to directly compute this value mod 997 by using the hint about how products and sums distribute over modulus.
Hope this helps!
I'm still not quite sure exactly what you're asking, but validating as to whether or not the parentheses are valid placement can be done using the following method. I used a similar one to go through hundred-page papers to ensure all parentheses were closed properly in the old days.
public static boolean isValid(String s) {
int openParens = 0;
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == '(') {
// we found an open paren
openParens++;
} else if (s.charAt(i) == ')') {
// we can close a paren
openParens--;
}
if (openParens < 0) {
// we closed a paren but there was nothing to close!
return false;
}
}
if (openParens > 0) {
// we didn't close all parens!
return false;
}
// we did!
return true;
}
You need to do implement this:
public static void main (String[]args) {
String str = "((1+2)*(3+4))-5";
if(isValid(str)){
expandString(str);
}
}
public static boolean isValid(String s) {
int totalParenthesis = 0;
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == '(') {
totalParenthesis++;
} else if (s.charAt(i) == ')') {
totalParenthesis--;
}
if (totalParenthesis < 0) {
return false;
}
}
if (totalParenthesis != 0) {
return false;
}
return true;
}
private static void expandString(String str) {
System.out.println("Called with : "+str);
if(!(str.contains("("))){
evalueMyExpresstion(str);
return;
}
String copyString=str;
int count=-1,positionOfOpen=0,positionOfClose=0;
for(Character character : str.toCharArray()) {
count++;
if(count==str.toCharArray().length){
evalueMyExpresstion(str);
return;
} else if(character.equals('(')) {
positionOfOpen=count+1;
} else if(character.equals(')')) {
positionOfClose=count;
copyString = str.substring(0, positionOfOpen - 1) + evalueMyExpresstion(
str.substring(positionOfOpen, positionOfClose)) + str.substring(positionOfClose + 1);
System.out.println("Call again with : "+copyString);
expandString(copyString);
return;
}
}
}
private static String evalueMyExpresstion(String str) {
System.out.println("operation : "+str);
String[] operation;
int returnVal =0;
if(str.contains("+")){
operation = str.split("\\+");
returnVal=Integer.parseInt(operation[0])+ Integer.parseInt(operation[1]);
System.out.println("+ val : "+returnVal);
return Integer.toString(returnVal);
} else if (str.contains("*")){
operation = str.split("\\*");
returnVal=Integer.parseInt(operation[0])* Integer.parseInt(operation[1]);
System.out.println("* val : "+returnVal);
return Integer.toString(returnVal);
} else if (str.contains("-")){
operation = str.split("\\-");
returnVal=Integer.parseInt(operation[0])- Integer.parseInt(operation[1]);
System.out.println("- val : "+returnVal);
return Integer.toString(returnVal);
}
System.out.println(str);
return Integer.toString(returnVal);
}
Output looks like:
Called with : ((1+2)*(3+4))-5
operation : 1+2
+ val : 3
Call again with : (3*(3+4))-5
Called with : (3*(3+4))-5
operation : 3+4
+ val : 7
Call again with : (3*7)-5
Called with : (3*7)-5
operation : 3*7
* val : 21
Call again with : 21-5
Called with : 21-5
operation : 21-5
- val : 16

Categories

Resources