I'm practicing algorithm problems and am trying to remove given letters from a string in o(n) time.
My attempt below is wrong in a couple of ways:
the last index in the outputString array is "undefined" and I'm not sure why.
my output is the right letter, but it's being returned for the length of the original string.
How can I fix these and why are these errors occurring?
function removeChars(lettersToDelete, string) {
var flags = {}; // a hash of letters to delete.
var outputString = string.split("");
var lettersToDelete = lettersToDelete.split("");
var i, j;
for (i = 0; i < lettersToDelete.length; i++) {
flags[lettersToDelete[i]] = true;
}
console.log(flags);
for (var j = 0; j < string.length; j++) {
if (flags[string[j]]) {
outputString[j++] = string[j];
}
}
console.log(outputString); //[ 'a', 'a', 'a', 'a', undefined ]
return outputString.join(""); // 'aaaa'
}
function removeChars(lettersToDelete, string) {
var flags = {}; // a hash of letters to delete.
var outputString = []; //string.split("");
var lettersToDelete = lettersToDelete.split("");
var i, j;
for (i = 0; i < lettersToDelete.length; i++) {
flags[lettersToDelete[i]] = true;
}
for (var j = 0; j < string.length; j++) {
if (!flags[string[j]]) {
outputString.push( string[j] );
}
}
console.log(outputString);
return outputString.join(""); // 'aaaa'
}
removeChars("itu", "mitul");
Related
Hi I have a problem how to search for words containing at least part of a word. What I mean words that have word I find in array javascript without built-in function except only PUSH.
This task requires no index.of, slice, substr, substring, regex etc. Only PUSH
This my code so far:
function wordsChecker(sentences, search) {
var result = []
for (var i = 0; i < sentences.length; i++) {
var isCheck = false
for (var j = 0; j < sentences.length; j++) {
for (var k = 0; k < search.length; k++) {
if (sentences[i][j] == search[k]) {
isCheck = true
}
}
}
if (isCheck == true) {
result.push(sentences[i])
}
}
return result
}
console.log(wordsChecker(['broom, room, rox, show room, stroom, root, rote, brother'], 'roo'))
//expected output : [broom, room, show room, stroom, root]
Thanks in advance
At the first you should make correct array. I hope this code work for you
function wordsChecker(sentences, search) {
var result = [], k = 0;
for (var i = 0; i < sentences.length; i++) {
var isCheck = false;
for (var j = 0; j < sentences[i].length; j++) {
while (k < search.length) {
if (sentences[i][j] == search[k]) {
isCheck = true;
k++;
break;
}
else {
isCheck = false;
k = 0;
break;
}
}
}
if (isCheck === true && k === search.length) {
result.push(sentences[i]);
k = 0;
}
}
return result;
}
console.log(wordsChecker(['broom', 'room', 'rox', 'show room', 'stroom', 'root', 'rote', 'brother'], 'roo'));
I am trying to generate a random words and push each one individually to the array, the problem is, i am getting list of words that starts from the first letter increased by one like this:
['a','ab','abc','abcd'] and so on
here is my code:
var word = "";
var texts = [];
var letters = "абвгдеёжзийклмнопрстуфхцчшщъыьэюя";
for (var i = 0; i < 10; i++){
word += letters.charAt(Math.floor(Math.random() * letters.length))
texts.push(
{
"id":i,
"name":word,
selected: false
}
)
}
what i need is to push a complete word to the list.
var texts = [];
var letters = "абвгдеёжзийклмнопрстуфхцчшщъыьэюя";
var wordLength = 5;
for (var i = 0; i < 10; i++){
let word = "";
for(var j = 0; j < wordLength; j++) {
word += letters.charAt(Math.floor(Math.random() * letters.length));
}
texts.push(
{
"id": i,
"name": word,
selected: false
}
)
}
You need to use another one loop for generate a words. New word's loop each time.
var word = "";
var texts = [];
var letters = "abcdefghijklmn";
for (var i = 0; i < 10; i++){
word = letters.slice(1,i)
texts.push(word);
}
alert(texts);
Oh, sorry you need it random;
how about this
var word = "";
var texts = [];
var letters = "abcdefghijklmn";
var l = letters.length;
var textsNum = 10;
for (var v = 0; v < textsNum; v++) {
for (var i = 0; i < l; i++) {
word += letters[Math.floor(Math.random() * l)];
}
texts.push(word);
word = '';
}
console.dir(texts);
I was hoping to get your assistance with this "Is Unique" algorithm in Javascript.
var allUniqueChars = function(string) {
// O(n^2) approach, no additional data structures used
// for each character, check remaining characters for duplicates
for (var i = 0; i < string.length; i++) {
console.log(i);
for (var j = i + 1; j < string.length; j++) {
if (string[i] === string[j]) {
return false; // if match, return false
}
}
}
return true; // if no match, return true
};
/* TESTS */
// log some tests here
allUniqueChars('er412344');
I am looking to log some tests, to see it display in the console. How do I call the function with unique strings to test it?
John
You can always create an Array with your strings and test like:
var allUniqueChars = function(string) {
// O(n^2) approach, no additional data structures used
// for each character, check remaining characters for duplicates
for (var i = 0; i < string.length; i++) {
for (var j = i + 1; j < string.length; j++) {
if (string[i] === string[j]) {
return false; // if match, return false
}
}
}
return true; // if no match, return true
};
/* TESTS */
// log some tests here
[
'er412344',
'ghtu',
'1234',
'abba'
].forEach(v => console.log(allUniqueChars(v)));
MDN Array.prototype.foreach
Run the snippet multiple times to generate unique random strings and display results:
var allUniqueChars = function(string) {
for (var i = 0; i < string.length; i++)
for (var j = i + 1; j < string.length; j++)
if (string[i] === string[j])
return false;
return true;
};
var getUniqueStr = () => Math.random().toString(36).substr(2, 9);
let myStringArray = [];
for(var i =0 ; i<8; i++) // 8 test cases in this example
myStringArray.push(getUniqueStr());
console.log(myStringArray.map(e=>e + " : " + allUniqueChars(e)));
You can use this function found here to generate random strings for testing (not mine!):
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (var i = 0; i < 5; i++)
text += possible.charAt(Math.floor(Math.random() * possible.length));
Below I am trying to give string arrays to a function that adds unique words to a words array, and if the word is already in the array to increase the count of the corresponding element in the count array:
var words = [];
var counts = [];
calculate([a, b]);
calculate([a, c]);
function calculate(result) {
for (var i = 0; i < result.length; i++) {
var check = 0;
for (var j = 0; i < tags.length; i++) {
if (result[i] == tags[j]) {
check = 1;
counts[i] = counts[i] + 20;
}
}
if (check == 0) {
tags.push(result[i]);
counts.push(20);
}
check = 0;
}
}
However the output turns out like this:
words = a, b
count = 2, 1
When I expect it to be:
words = a,b,c
count = 2,1,1
Thanks for any help in advance
Breaking the problem down into methods with good names helps you to work out your logic.
Try this:
<script type="text/javascript">
var words = [];
var counts = [];
calculate(["a", "b"]);
calculate(["a", "c"]);
console.log(words);
console.log(counts);
function calculate(result) {
for (var i=0; i<result.length; i++) {
if (array_contains(words, result[i])) {
counts[result[i]]++;
} else {
words.push(result[i]);
counts[result[i]] = 1;
}
}
}
function array_contains(array, value) {
for (var i=0; i<array.length; i++)
if (array[i] == value)
return true;
return false;
}
</script>
Output:
["a", "b", "c"]
[]
a 2
b 1
c 1
Please check this :
you can test it on : http://jsfiddle.net/knqz6ftw/
var words = [];
var counts = [];
calculate(['a', 'b']);
calculate(['a', 'c']);
calculate(['a', 'b', 'c']);
function calculate(inputs) {
for (var i = 0; i < inputs.length; i++) {
var isExist = false;
for (var j = 0; j < words.length; j++) {
if (inputs[i] == words[j]) {
isExist = true
counts[i] = counts[i] + 1;
}
}
if (!isExist) {
words.push(inputs[i]);
counts.push(1);
}
isExist = false;
}
}
console.log(words);
console.log(counts);
Output is :
["a", "b", "c"] (index):46
[3, 2, 2]
A few things were wrong, here's working code:
var words = [];
var counts = [];
calculate(["a", "b"]);
calculate(["a", "c"]);
function calculate(result) {
for (var i = 0; i < result.length; i++) {
var check = 0;
for (var j = 0; j < words.length; j++) {
if (result[i] == words[j]) {
check = 1;
++counts[j];
}
}
if (check == 0) {
words.push(result[i]);
counts.push(1);
}
check = 0;
}
}
Jsbin : http://jsbin.com/hawaco/2/edit?js,console
Things I've changed:
Changed array literal to supply strings instead of variable names: [a,b] to ["a","b"]
Replaced instances of tags (presumably an old name) with words
Changed the 20s to 1s
Made the increment of counts[j] more clear
Fixed use of i/j indices
Things to consider:
Perhaps make this a dictionary rather than a pair of arrays: {"a":1, "b":2}, which would make for simpler code
Pass in the names of the arrays to permit other accumulators, or combine the method and arrays into a single object
Simplified:
var seen = {};
count(["a", "b"], seen);
count(["a", "c"], seen);
function count(words, accumulator) {
for (var i = 0; i < words.length; ++i) {
if(!accumulator.hasOwnProperty(words[i])) {
accumulator[words[i]] = 1;
} else {
++accumulator[words[i]];
}
}
}
Result:
>> seen
[object Object] {
a: 2,
b: 1,
c: 1
}
JSBin: http://jsbin.com/halak/1/edit?js,console
Here's my solution (using an object):
const checkWord = (str) => {
let collection = {};
// split the string into an array
let words = str.split(' ');
words.forEach((word) => {
collection[word] = word;
});
// loop again to check against the array and assign a count
for (let j = 0; j < words.length; j++) {
if (words[j] === collection[words[j]]) {
collection[words[j]] = 0;
}
collection[words[j]]++
}
console.log(collection);
};
You can also use reduce:
const checkWord = (str) => {
let collection = {};
let words = str.split(' ');
words.forEach((word) => {
collection[word] = word;
});
for (var i = 0; i < words.length; i++) {
if (words[i] === collection[words[i]]) {
collection[words[i]] = 0;
}
}
let total = words.reduce((occurrences, word) => {
collection[word]++
return collection;
}, 0);
console.log(total);
};
function longestWord(string) {
var str = string.split(" ");
var longest = 0;
var word = null;
for (var i = 0; i < str.length; i++) {
var checkedLetters = "";
for (var j = 0; j < str[j].length; j++) {
if (j == /[^a-zA-Z]/) {
checkedLetters += j;
}
if (longest < checkedLetters.length) {
longest = checkedLetters.length;
word = checkedLetters;
}
}
}
return word;
}
Is there something wrong with my use of regex? When I call longestWord("Hello, I am here") I want it to return "Hello" (without the comma), but it returns null.
Just wrote this little snippet, might help you out:
function longestWord(string){
return string.match(/[a-zA-Z]+/g)
.reduce(function(a,b){
return a.length>=b.length?a:b;
})
}
/[a-zA-Z]+/g matches all words in the string, and returns an array of them. Your test string above ("Hello, I am here") will become ["Hello","I","am","here"] when this RegEx is run on it.
Once I have this array, it is simply a matter of looping through it to find the longest word. I accomplished this by using .reduce.
There are some mistake in your code:
for (var j = 0; j < str[j].length; j++) {
should be
for (var j = 0; j < str[i].length; j++) {
And
if (j == /[^a-zA-Z]/) {
Should be:
if (/[a-zA-Z]/.test(str[i][j])) {
Your final code should be:
function longestWord(string) {
var str = string.split(" ");
var longest = 0;
var word = null;
for (var i = 0; i < str.length; i++) {
var checkedLetters = "";
for (var j = 0; j < str[i].length; j++) {
if (/[a-zA-Z]/.test(str[i][j])) {
checkedLetters += str[i][j];
}
}
if (longest < checkedLetters.length) {
longest = checkedLetters.length;
word = checkedLetters;
}
}
return word;
}
Check demo
The big (non-typo) problem with how you’re using regular expressions is that the method is .test; == will test whether the string is equal to the string representation of the regular expression.
Just use .match and a little bit of sort magic!
function longestWord(string){
var words = string.match(/\w+/g);
words.sort(function(a, b) { return b.length - a.length; });
// Firefox 22.0 promotion:
// words.sort((a, b) => a.length - b.length);
return words[0];
}
You don't need to use Regex, you can just use .length to search for the longest string.
i.e.
function longestWord(string) {
var str = string.replace(/[\.,-\/#!$%\^&\*;:{}=\-_`~()]/g,"").split(" ");
longest = str[0].length;
longestWord = str[0];
for (var i = 1; i < str.length; i++) {
if (longest < str[i].length) {
longest = str[i].length;
longestWord= str[i];
}
}
return longestWord;
}
EDIT: You do have to use some Regex...