Sort string without any builtin methods - javascript

I want to sort a string in javascript without using a built in method, just by using for's and comparisons like 'a' > 'b';
Something that doesn't work:
function replaceAt(str, i, char) {
return str.substr(0,i) + char + str.substr(i + 1)
}
function swap(str, i1, i2) {
return replaceAt(replaceAt(str, i1, str[i2]),i2,str[i1]);
}
function sort(str) {
var sorted = str;
for (var i = 0; i < str.length; i++) {
if (str[i] > str[i + 1]) {
str = swap(str, i, i+1)
}
}
return str;
}
Pseudo-code or books, courses recommendations on programming are welcome!

Your code is not applying any sort algorithm logic, I recommend you to read atleast 1 to solve your problem.
Below is the program, which produces the expected output from your program using selection sort.
swap and replace functions works fine.
function sort(str) {
var sorted = str;
//Selection sort
for (var i = 0; i < str.length; i++) {
for(var j = i + 1; j < str.length - 1; j++) {
if (str[i] < str[j]) {
str = swap(str, i, j)
}
}
}
return str;
}
console.log(sort("zaasfweqrouoicxzvjlmmknkniqwerpopzxcvdfaa"));
//output: aaaaccdeeffiijkklmmnnoooppqqrrsuvvwwxxzzz

function sort(arr) {
arr = arr.split("");
for (i = 0; i < arr.length; i++) {
for (j = 0; j < arr.length; j++) {
if (arr[j] > arr[i]) {
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
return arr.join("");
}
console.log(sort("dcna"));

function sort(arr) {
arr = arr.split("");
for (i = 0; i < arr.length; i++) {
for (j = 0; j < arr.length; j++) {
if (arr[j] > arr[i]) {
[arr[j], arr[j+1]] = [arr[j+1], arr[j]]
}
}
}
return arr.join("");
}
console.log(sort("dcna"));
Note: no need of using temp variable

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
array=[4, 10, 2, 9, 6, 3, 13, 5];
function arrayOperations()
{
var count = array.length - 1,
temp,
j,
i;
for (j = 0; j < count; j++)
{
for (i = 0; i < count; i++)
{
if (array[i] > array[i + 1])
{
temp = array[i + 1];
array[i + 1] = array[i];
array[i] = temp;
}
}
}
document.write("ascending order is <br>")
for(k=0;k<=array.length-1;k++){
document.write(array[k]+ "<br>");
}
document.write("descending order is <br>")
for(k=array.length-1;k>=0;k--){
document.write(array[k]+ "<br>");
}
document.write("biggest number is <br>")
for(k=array.length-1;k>=0;k--){
if((array[k])>array[k-1]){
document.write(array[k]+"<br>")
break;
}
}
document.write("smallest number is <br>")
for(k=0;k<=array.length;k++){
if((array[k])<array[k+1]){
document.write(array[k]+"<br>")
break;
}
}
}
</script>
<title></title>
</head>
<body>
array=[4, 10, 2, 9, 6, 3, 13, 5]
<br>
<input type="button" onclick="arrayOperations()" value="find">
</body>
</html>

//generic sort function to sort a word
function sortArray(str){
let strr = str.split('');
for(var index = 0 ;index <strr.length ;index ++ ){
for(var index1 = 0;index1<(strr.length-index) ;index1++){
let temp;
if( strr[index1] > strr[index1+1] ){
temp = strr[index1] ;
strr[index1] = strr[index1 +1];
strr[index1+1] =temp;
}
}
}
return(strr.join(''));
}
//data set to sort
let data = "Hey Goodmorning How are you";
let result;
let data1 =data.split(' ');
data1.forEach(value => {
value = sortArray(value.toLowerCase());
if(result){
result += " ";
result += value;
}
else {result = value;}
});
console.log(result);

Related

How to pass array to function as argument in javaScript?

I want to map array element and return true or false if for example there is the summation of two numbers in my array equal 8.
bad way
function showNumbered(arr) {
for(let i = 0; i < arr.length; i++) {
for(let x = 0; x < arr.length; x++) {
if( arr[i] + arr[x] == 8 ) {
console.log(true);
}else{
console.log(false);
}
}
}
}
Make sum of each with each number value in array.
If there is a sum that is equal to 8 returns true else return false
var array = [3, 6, 2, 8, 4, 7];
function arrSum(arr) {
var ret = true;
for (var i = 0; i < arr.length; i++) {
for (var ii = i+1; ii < arr.length; ii++) {
if (arr[i] + arr[ii] === 8) {
console.log(arr[i], '+', arr[ii], '=', true);
ret = false;
}
}
}
if(ret) { console.log(false); }
}
arrSum(array);
"how to pass array to function as argument"
function showNumbered(arr) {
for(let i = 0; i < arr.length; i++) {
for(let x = 0; x < arr.length; x++) {
if( arr[i] + arr[x] == 8 ) {
console.log(true);
}else{
console.log(false);
}
}
}
}
const arr = [1,2,3,4,5,6]
showNumbered(arr)
you can do it in linary way. O(n)
function showNumbered(arr, target) {
const complementary = new Map();
for(let i = 0; i < arr.length; i++) {
if(complementary.has(arr[i])){
console.log(complementary.get(arr[i]), i)
}
complementary.set(target - arr[i], i)
}
}
showNumbered([1,3,5,6,8,3,4], 4)

Generate chunks from string

before going to problem, i want to generate dynamically like
temp = word[i] for 2,
temp = word[i-1] + word [i] for 3,
temp = word[i-2] + word[i-1] + word [i] for 4
I explained with code and what i have tried
function produceTwoChArray(word) {
var temp = "";
var tempArr = [];
for (var i = 0; i < word.length; i++) {
temp += word[i];
if (temp.length === 2) {
tempArr.push(temp);
}
temp = word[i];
}
return tempArr;
}
produceTwoChArray("breaking")
above code will produce result as :
["br", "re", "ea", "ak", "ki", "in", "ng"]
So inside the for loop if i change to below codes to produce three letters then
if (temp.length === 3) {
tempArr.push(temp);
}
temp = word[i-1] + word[i];
Result:
["bre", "rea", "eak", "aki", "kin", "ing"]
so adding word[i-1], word[i-2] with temp length 3, 4 and so on..
For dynamically creating the temp statement, i created these Function
1)
function generateWordSequence(n) {
var n = n - 2;
var temp1 = [];
for (var j = n; j >= 0; j--) {
temp1.push("word[i - " + j + "]");
}
temp1 = temp1.join('+').toString();
return temp1;
}
2)
function generateWordSequence(n, word) {
var n = n - 2;
var temp1 = "";
for (var j = n; j >= 0; j--) {
temp1 = temp1 + word[i - j];
}
return temp1;
}
But both above try's are returning as string so it didnt work. When i invoke above fn in produceTwoChArray fn like this
function produceTwoChArray(word, n) {
var temp = "";
var tempArr = [];
var retVar = generateWordSequence(n, word);
for (var i = 0; i < word.length; i++) {
temp += word[i];
if (temp.length === n) {
tempArr.push(temp);
}
temp = retVar;
}
return tempArr;
}
When i tried those all logic inside produceTwochArray itself , i also didnt work.
Please help me out here.
You could take a double slice with mapping part strings.
function part(string, count) {
return [...string.slice(count - 1)].map((_, i) => string.slice(i, i + count));
}
console.log(part("breaking", 2));
console.log(part("breaking", 3));
console.log(part("breaking", 4));
You can use slice method in order to obtain a more easy solution.
function produceArray(str,n){
return str=str.split('').map(function(item,i,str){
return str.slice(i,i+n).join('');
}).filter(a => a.length == n);
}
console.log(produceArray("breaking",2));
console.log(produceArray("breaking",3));
console.log(produceArray("breaking",4));
console.log(produceArray("breaking",5));
console.log(produceArray("breaking",6));

Output the sorted array to main element

I am new to javascript and working with DOM, so please bear with me.
I have an array called num that I want to sort and display. The sort is a selection sort that returns the number of moves it took.
I can display the unsorted array but can't figure out how to call my sort function and then display the sorted array to the screen. My code is below:
function fn(a, b) {
if (a < b)
return true;
}
function selection(list, fun) {
var min, temp, count,
len = list.length;
for (var i = 0; i < len; i++) {
min = i;
for (var j = i + 1; j < len; j++) {
if (fun(list[j], list[min])) {
min = j;
}
}
temp = list[i];
list[i] = list[min];
listlist
list[min] = temp;
count += 3;
}
return count;
}
var num = [10, 1, 3, 5, 2, 9, 8, 6, 7, 4];
var demoP = document.getElementById("content");
{
var html = "";
html += "Original:" + num + "<br>";
selection(num, fn);
html += "Sorted:" + num + "<br>";
}
demoP.innerHTML = html;
<div id="content"></div>
arr is undefined, you should use list instead. Returning count returns the number of operations (after it's been initialized), return list instead. And as list is local to the function, you need to set num to the return value of the function call.
<span id='content'/>
<script>
function fn(a, b) {
if (a < b)
return true;
}
function selection(list, fun) {
var min, temp, count=0,
len = list.length;
for (var i = 0; i < len; i++) {
min = i;
for (var j = i + 1; j < len; j++) {
if (fun(list[j], list[min])) {
min = j;
}
}
temp = list[i];
list[i] = list[min];
list[min] = temp;
count += 3;
}
return list;
}
var num = [10, 1, 3, 5, 2, 9, 8, 6, 7, 4];
var demoP = document.getElementById("content");
var html = "";
html += "Original:" + num + "<br>";
num= selection(num, fn);
html += "Sorted:" + num + "<br>";
demoP.innerHTML = html;
</script>

Check if string contains substring without using any standard JavaScript methods?

So I need to implement a javascript method which will return true or false depending on if the masterString contains a subString.
I did something like following but not sure if this is the right approach :
function contains(masterString, subString) {
if(subString.length > masterString.length){
return false;
}
for(var i=subString.length-1; i<masterString.length; i++){
if(concatString(i - subString.length-1, i, masterString) === subString){
return true;
}
}
return false;
}
function concatString(index1, index2, string){
var conString = '';
console.log(index1, index2-1, string);
for(var i=index1; i<index2-1; i++){
conString += string[i];
}
console.log(conString);
return conString;
}
contains('abcd', 'bc');
It isn't working fine though.
Can we implement it? Thanks :)
For each possible index, test if subString is on that index of masterString.
var indexOf = function(masterString,subString){
for(var i = 0 ; i < masterString.length - subString.length + 1; i++){
var match = true;
for(var j = 0; j < subString.length; j++){
if(masterString[i + j] !== subString[j]){
match = false;
break;
}
}
if(match)
return i;
}
return -1;
}
var contains = function(master,sub){
return indexOf(master,sub) !== -1;
}
Note: There are faster algorithms to achieve that like Knuth–Morris–Pratt.
You have a good solution. But I think mine is easier.
By the way: I think .length is a javascript funciton too.
function length(string){
var count = 0;
while(string[count] != undefined)
count++;
return count;
}
function contains(masterString, subString) {
var masterStringLength = length(masterString);
var subStringLength = length(subString);
for(var i = 0; i <= masterStringLength - subStringLength; i++)
{
var count = 0;
for(var k = 0; k < subStringLength; k++)
{
if(masterString[i + k] == subString[k])
count++;
else
break;
}
if(count == subStringLength)
return true;
}
return false;
}
console.log(contains('abcdefgh', 'bcde'));
console.log(contains('abcdefgh', 'ab'));
console.log(contains('abcdefgh', 'fgh'));
You can use a nested loop:
function contains(masterString, subString) {
outerloop:
for(var i=0; i <= masterString.length-subString.length; ++i) {
for(var j=0; j<subString.length; ++j)
if(masterString[i + j] !== subString[j]) continue outerloop;
return true;
}
return false;
}
Of course, using native methods you could achieve better performance.
This is similar to longest common subsequence See this.
this code solves your issue.
function contains(masterString, subString) {
if (findCommonSubsequence(masterString, subString) == subString)
alert(true);
else
alert(false);
}
function findCommonSubsequence(a, b) {
var table = [],
aLen = a.length,
bLen = b.length;
squareLen = Math.max(aLen, bLen);
// Initialize a table of zeros
for (var i = 0; i <= squareLen ; i++) {
table.push([]);
for (var j = 0; j <= squareLen; j++) {
table[i][j] = 0;
}
}
// Create a table of counts
for (var i = 1; i <= aLen; i++) {
for (var j = 1; j <= bLen; j++) {
if (a[i - 1] == b[j - 1]) {
table[i][j] = table[i - 1][j - 1] + 1;
} else {
table[i][j] = Math.max(table[i - 1][j], table[i][j - 1]);
}
}
}
// Move backwards along the table
i = aLen, j = bLen, LCS = [];
while (i > 0 && j > 0) {
if (a[i - 1] == b[j - 1]) {
LCS.push(a[i - 1]);
i -= 1;
j -= 1;
} else {
if (table[i][j - 1] >= table[i - 1][j]) {
j -= 1;
} else {
i -= 1;
}
}
}
return(LCS.reverse().join(''));
}
Your question doesn't have enough odd constraints, so let's do it
without for-loops as well, with some help from ES6.
// Cf. Array.prototype.some
const any = (f, [x,...xs]) =>
x === undefined ? false : f(x) || any(f,xs);
// Return true if the first iterable is a prefix of the second.
const isprefix = ([x,...xs], [y,...ys]) =>
x === undefined ? true : x == y && isprefix(xs,ys);
// tails('abc') --> [['a','b','c'], ['b','c'], ['c']]
const tails = ([x,...xs]) =>
x === undefined ? [] : [[x,...xs],...tails(xs)];
// If needle is empty, or is a prefix of any of tails(haystack), return true.
const contains = (haystack, needle) =>
needle.length ? any(bale => isprefix(needle, bale), tails(haystack)) : true;
const tests = [
['aaafoobar', 'foo'],
['foo', 'foo'],
['fo', 'foo'],
['', 'f'],
['f', ''],
['', '']
];
tests.forEach(test => console.log(JSON.stringify(test), contains(test[0], test[1])));
You can do like this
var substr = "test",
masterstr = "test1",
checksubstr = (ms,ss) => !!~ms.indexOf(ss);
console.log(checksubstr(masterstr,substr));

Fill 2D array in alternate squares

You have a value n, it will determine the dimension of a 2D array or table. Then you should fill the array or the table from the outer layer to the center once with ones and once with zeros up to the point where there is no other element to write.
n=5
n=6
Have been trying this for a long time now, would appreciate any help. Am able to fill the boundaries nothing more.
My latest code :
function fillArray(n) {
var exArray = [];
var html = '';
for (var i = 0; i < n; i++) {
html+= '<tr>';
exArray[i] = [];
for (var j = 0; j < n; j++) {
exArray[i][j] = 0;
if(i%(n-1)==0 || j%(n-1)==0) {
exArray[i][j] = 1;
}
html+='<td class="text-center">'+exArray[i][j]+' ['+i+','+j+']</td>';
};
html+= '</tr>';
};
return html;
}
I think the simplest way is considering only the top-left quadrant, and fill the others by symmetry:
var arr = Array(n);
for(var i=0; i<n/2; ++i) {
arr[ i ] = new Array(n);
arr[n-1-i] = new Array(n);
for(var j=0; j<n/2; ++j)
arr[ i ][j] = arr[ i ][n-1-j] =
arr[n-1-i][j] = arr[n-1-i][n-1-j] =
+ !(Math.min(i,j) % 2);
}
function fillArray(n) {
var arr = Array(n);
for(var i=0; i<n/2; ++i) {
arr[ i ] = new Array(n);
arr[n-1-i] = new Array(n);
for(var j=0; j<n/2; ++j)
arr[ i ][j] = arr[ i ][n-1-j] =
arr[n-1-i][j] = arr[n-1-i][n-1-j] =
+ !(Math.min(i,j) % 2);
}
var table = document.createElement('table');
for(var i=0; i<n; ++i) {
var row = table.insertRow();
for(var j=0; j<n; ++j)
row.insertCell().textContent = arr[i][j];
}
return table;
}
document.body.appendChild(fillArray(9));
td {
width: .8em;
height: .8em;
line-height: .8em;
}
Not as succinct but works:
var n = 10;
function isMiddleIndex(middleIdx, rowIndex, cellIndex) {
return middleIdx.indexOf(rowIndex) != -1 && middleIdx.indexOf(cellIndex) != -1;
}
function isBoundaryIndex(n, boundsIdx, i, j) {
return boundsIdx.indexOf(i) > -1 || boundsIdx.indexOf(j) > -1;
}
function fillArray(n) {
var num,
html = '',
nMid = n / 2,
middleIdx = n % 2 == 1 ? [(n - 1) / 2] : [Math.floor(nMid) - 1, Math.ceil(nMid)],
boundsIdx = [0, n - 1];
for (var i = 0; i < n; i++) {
html += '<tr>';
for (var j = 0; j < n; j++) {
num = isMiddleIndex(middleIdx, i, j) || isBoundaryIndex(n, boundsIdx, i, j) ? 1 : 0;
html += '<td class="text-center">' + num + '</td>';
};
html += '</tr>';
};
return html;
}
$('table').html(fillArray(n));
DEMO
A more readable way
function fillArray(n) {
var exArray = [];
for (var i = 0; i < n; i++) {
exArray[i] = [];
for (var j = 0; j < n; j++) {
exArray[i][j] = 0;
if(i < j) {
if(n - j - 1 > i) {
if(i % 2 == 0) {
exArray[i][j] = 1;
}
}
else {
if((n - j - 1) % 2 == 0) {
exArray[i][j] = 1;
}
}
}
else {
if(j > n - i - 1) {
if((n - i - 1) % 2 == 0) {
exArray[i][j] = 1;
}
}
else {
if(j % 2 == 0) {
exArray[i][j] = 1;
}
}
}
};
};
}
And Fiddle.

Categories