Delaying a string function? - javascript

So basically I all my code is within a while loop. Within that I have a for loop which checks for a bee in the neighboruging grids. When it detects a bee it calls a function. I need all the functions called by that to wait and only run when the while loop is just about to be finsihed (outside the for loop but inside the while loop).
Here is my code:
Cell.prototype.floodFillEach = function() {
grid[orginalX][orginalY].floodFill();
while(repeat<=7){
for (var xoff = 0-x12; xoff <= 0+x12; xoff++) {
for (var yoff = 0; yoff <= 0+x12; yoff++) {
var i = orginalX + xoff;
var j = orginalY + yoff;
if (i > -1 && i < cols && j > 0 && j < rows) {
var neighbour = grid[i][j];
if (neighbour.marked2) {
console.log("x:"+i+" y:"+j);
neighbour.floodFill(); // everytime this function is called within this while loop i need it to wait untill...
}
}
}
}
// ... here. I need the functions called to wait and run here and after they are done only then proceed with the rest of this while loop
x12++
repeat++
}
}

Store in an array, then call at the end.
Cell.prototype.floodFillEach = function() {
grid[orginalX][orginalY].floodFill();
while(repeat<=7){
const neighboursToFloodFill = [];
for (var xoff = 0-x12; xoff <= 0+x12; xoff++) {
for (var yoff = 0; yoff <= 0+x12; yoff++) {
var i = orginalX + xoff;
var j = orginalY + yoff;
if (i > -1 && i < cols && j > 0 && j < rows) {
var neighbour = grid[i][j];
if (neighbour.marked2) {
console.log("x:"+i+" y:"+j);
neighboursToFloodFill.push(neighbour);
}
}
}
}
for (const neighbour of neighboursToFloodFill) {
neighbour.floodFill();
}
x12++
repeat++
}
}

Related

Adding and removing event listeners with argument bearing functions

Alright, first time posting here. I have been looking at posts regarding this issue for days now and I can't find a fix.
I have a matrix of images (basically arranged spheres) with unique id's. I want to add different functionalities to said spheres. So I proceed to add event listeners. All good so far. After the first event is triggered I want all the spheres to change their event listener, so I proceed to remove all event listeners and add new ones. I cannot remove the event listeners.
Adding event:
for (let i = 0; i < 11; i++) {
for (let j = 0; j < 11; j++) {
if ((i > 1 && i < 9 && j > 1 && j < 9) && checkCorners(i, j) === true) {
let ball = document.getElementById(i.toString() + j.toString());
ball.addEventListener('click', removeBall(i, j));
}
}
}
removeBall():
var removeBall = function(i, j) {
return function curried_func(ii, jj) {
let ball = document.getElementById(i.toString() + j.toString());
ball.src = "./public/assets/ball_empty.png";
}
}
I'm using the curried function method because it's the last method I have tried, besides retrieving object data from the e (event) argument, which did not seem to work as e was undefined. Or using a handler. Or using binding.
Removing event:
for (let i = 0; i < 11; i++) {
for (let j = 0; j < 11; j++) {
if ((i > 1 && i < 9 && j > 1 && j < 9) && checkCorners(i, j) === true) {
let ball = document.getElementById(i.toString() + j.toString());
// ball.somethingToRevmoveEvent?
}
}
}
I do feel the need to mention it's also my first javascript serious project so if anyone has a better solution or workaround (instead of adding and removing events 100 times for functionalities) please do share.
matrix for reference
-the user should remove 1 ball , at which point the spot turns black, and then any ball can jump over another to fill the empty spot (the "jumped over ball" gets removed). I think it's a chinese checker puzzle of some kind.
While the currying is nice, it means that it returns a new function each time it is called, rather than a copy of the same function. You need to somehow hold a reference to the function that is being bound, and then use it when removing the event listener. Without the context of the rest of your code I will attempt to pseudo-code it a bit below:
const eventMap = new Map();
function getMapKey(i, j) {
return `${i},${j}`;
}
function addEvents() {
for (let i = 0; i < 11; i++) {
for (let j = 0; j < 11; j++) {
if ((i > 1 && i < 9 && j > 1 && j < 9) && checkCorners(i, j) === true) {
let ball = document.getElementById(i.toString() + j.toString());
let removeBallFn = removeBall(i, j);
let key = getMapKey(i, j);
eventMap.set(key) = removeBallFn;
ball.addEventListener('click', removeBallFn);
}
}
}
}
function removeEvents() {
for (let i = 0; i < 11; i++) {
for (let j = 0; j < 11; j++) {
if ((i > 1 && i < 9 && j > 1 && j < 9) && checkCorners(i, j) === true) {
let ball = document.getElementById(i.toString() + j.toString());
let key = getMapKey(i, j);
let removeBallFn = eventMap.get(key) = removeBallFn;
ball.removeEventListener('click', removeBallFn);
eventMap.delete(key);
}
}
}
}
This is untested as I don't have the rest of your code. The principle is that each time we generate a "remove" function, we store it in the Map (eventMap here) using a unique key based on a concatenation of the i and j values at that point in the loop. Then, when we got to remove, pull the same "remove" function out of the map using the same key, and pass it to removeEventListener.
There are other ways to do this-- this is just one option. Adjust as needed given the larger context of your code. Hopefully this works for you!
Adding Event
for (let i = 0; i < 11; i++) {
for (let j = 0; j < 11; j++) {
if ((i > 1 && i < 9 && j > 1 && j < 9) && checkCorners(i, j) === true) {
let ball = document.getElementById(i.toString() + j.toString());
ball.addEventListener('click', removeBall[i][j]);
}
}
}
removeBall
var removeBall = [];
for (let i = 0; i < 11; i ++) {
removeBall[i] = [];
for (let j = 0; j < 11; j ++) {
removeBall[i][j] = () => {
let ball = document.getElementById(i.toString() + j.toString());
ball.src = "./public/assets/ball_empty.png";
}
}
}
Removing Event
for (let i = 0; i < 11; i++) {
for (let j = 0; j < 11; j++) {
if ((i > 1 && i < 9 && j > 1 && j < 9) && checkCorners(i, j) === true) {
let ball = document.getElementById(i.toString() + j.toString());
ball.removeEventListener('click', removeBall[i][j]);
}
}
}
Well, I suggest you use event delegation instead of touching event listener to 100 or more elements one by one. You can read this post on how it works. Then, you just need to add one event listener to the parent node of all your images. If you want to remove the event listener, it's simple, just use removeEventListener by passing your event listener previously defined. So, there is no need to massively add and remove event listeners.
For example, assuming you have the following html structure, and your ball is an <img> element:
<div id="image-container">
<img id="[Image Id]">
...
</div>
You can add event lister like this:
let imageContainer = document.querySelector('#image-container');
imageContainer.addEventListener('click', removeBall);
function removeBall(event) {
let ball = event.target
if ( ball && ball.nodeName == "IMG") {
ball.src = "./public/assets/ball_empty.png";
}
}
...
and remove event listener
imageContainer.removeEventListener('click', removeBall)
Later, if you want to add a different listener, and remove it later. Just repeat the above steps. Hope it helps ~

Javascript: Can't find errors in graphical genetic algorithm

I'm quite new to Javascript, and I've been working on a graphic-based genetic algorithm. However, I think I'm getting some tunnel vision after working on it a while and I can't seem to catch what's going wrong?
I'm using Javascript with p5.js.
Problem described below.
Premise
Create a bunch of red dots with probability-based movement. Fitness determined by how many randomly placed green dots they eat. Evolve to eat more.
Errors
When I run it, a green dot always appears in the upper left even though they should be randomly placed.
(RESOLVED) The breeding function doesn't seem to work properly. It should:
Create an array for the next generation (this works)
Draw random parents from mating pool (this works)
Randomly cross their chromosome arrays to form a new individual (not sure)
Apply mutation chance for each new individual (not sure)
Store offspring in the new generation (this works)
Replace a random offspring with fittest member of last generation (not sure)
Replace current generation array with new generation array (not sure)
Code
var settings = {
populationSize : 25,
geneLength : 8,
mutationProbability : 0.01,
forestSize : 1500,
rows : 124,
cols : 249,
year : 250,
end : 20,
};
function onCanvas(position){
return position*4+2;
}
function randombetween(min, max){
return Math.random()*max;
}
//set up sheep
var population = new Population(settings.populationSize, settings.geneLength);
function Sheep(g, dna){
this.genLen = g;
this.state = 0;
this.fitness=0;
this.xpos = Math.floor(Math.random()*settings.cols);
this.ypos = Math.floor(Math.random()*settings.rows);
this.chromosome = new Array(this.genLen);
if (dna != null){
this.chromosome = dna;
} else{
for(var x=0; x<this.genLen; x+=4){
this.chromosome[x] = Math.random();
this.chromosome[x+1] = randombetween(0, 1-this.chromosome[x]);
this.chromosome[x+2] = randombetween(0, 1-this.chromosome[x]-this.chromosome[x+1]);
this.chromosome[x+3] = 1-this.chromosome[x]-this.chromosome[x+1]-this.chromosome[x+2];
}
}
}
function Population(p, g){
this.popSize = p;
this.sheep = [];
this.matingPool = [];
this.maxFit;
this.maxFitIndex;
for (var x = 0; x < this.popSize; x++) {
this.sheep[x] = new Sheep(g, null);
}
this.evaluate = function() {
//find maximum fitness in generation
this.maxFit = 0;
this.maxFitIndex = 0;
for (var x = 0; x < this.popSize; x++) {
//this.sheep[x].calcFitness();
if (this.sheep[x].fitness > this.maxFit){
this.maxFitIndex = x;
this.maxFit = this.sheep[x].fitness;
}
}
//document.write("Maximum fitness: " + this.maxFit);
//normalize fitness
for (var i = 0; i < this.popSize; i++) {
this.sheep[i].fitness /= this.maxFit;
}
//reset mating pool every generation
this.matingPool = [];
//higher fitness means more representation in the pool
for (var i = 0; i < this.popSize; i++) {
var n = this.sheep[i].fitness *10;
for (var j = 0; j < n; j++) {
this.matingPool.push(this.sheep[i]);
}
}
}
//create children sheep
this.breed = function (){
var newsheep = [];
for (var i = 0; i < this.popSize; i++){
//pick random parents from the mating pool
let parentA = this.matingPool[Math.floor(Math.random()*this.matingPool.length)];
let parentB = this.matingPool[Math.floor(Math.random()*this.matingPool.length)];
//parent genes are randomly crossed
var newchromosome = [];
var midpoint = Math.floor(Math.random()*g);
for (var j = 0; j < g; j++){
if (j > midpoint){
newchromosome[j] = parentA.chromosome[j];
} else{
newchromosome[j] = parentB.chromosome[j];
}
}
//offspring may be mutated
if(Math.random()<=settings.mutationProbability){
newchromosome[Math.floor(Math.random()*g)]=Math.floor(Math.random()*10+1);
}
newsheep[i] = new Eater(g, newchromosome);
}
//elite offspring survive into next generation, replacing a random offspring
var random = Math.floor(Math.random()*this.popSize);
if(Math.random()<=settings.mutationProbability){
this.sheep[this.maxFitIndex].chromosome[Math.floor(Math.random()*g)]=Math.floor(Math.random()*10+1);
}
for(var x = 0; x < g; x++){
newsheep[random].chromosome[x] = this.sheep[this.maxFitIndex].chromosome[x];
}
//update array of sheep
for(var x=0; x<this.popSize; x++){
this.sheep[x] = newsheep[x];
}
}
}
//set up trees
var forest = new Forest(settings.forestSize);
function radialTreePopulation(x,y,r,count){
let trees = [];
for(let i = 0;i < count; i++){
trees.push({
posx : (x + Math.floor((Math.random()* r) * (Math.random() < 0.5 ? -1 : 1))),
posy : (y + Math.floor((Math.random()* r) * (Math.random() < 0.5 ? -1 : 1)))
});
}
return trees;
}
function Forest(f){
this.forSize = f/ 75;
this.trees = [];
for (var x = 0; x < this.forSize ; x++) {
this.trees.push(...radialTreePopulation(
(Math.floor(Math.random()*(settings.cols-20)+10))| 0,
(Math.floor(Math.random()*(settings.rows-20)+10))| 0,
11,
75)
);
}
}
//evaluate how to move
function moveHungry(x, move){
if(move<population.sheep[x].chromosome[0]){
return 0;
}
else if(move-population.sheep[x].chromosome[0]<population.sheep[x].chromosome[1]){
return 1;
}
else if(move-population.sheep[x].chromosome[0]-population.sheep[x].chromosome[1]<population.sheep[x].chromosome[2]){
return 2;
}
else{
return 3;
}
}
function moveEaten(x,move){
if(move<population.sheep[x].chromosome[4]){
return 0;
}
else if(move-population.sheep[x].chromosome[4]<population.sheep[x].chromosome[5]){
return 1;
}
else if(move-population.sheep[x].chromosome[4]-population.sheep[x].chromosome[5]<population.sheep[x].chromosome[6]){
return 2;
}
else{
return 3;
}
}
//count generations and days
var generation=0;
var counter = 0;
//create world
function createWorld(){
background("lightblue");
fill(0,255,0);
for(var x=0; x<settings.forestSize; x++){
rect(onCanvas(forest.trees[x].posx), onCanvas(forest.trees[x].posy), 4, 4);
}
fill(255,0,0);
for(var x=0; x<settings.populationSize; x++){
population.sheep[x].state=0;
rect(onCanvas(population.sheep[x].xpos), onCanvas(population.sheep[x].ypos), 4, 4);
}
//remove eaten trees
for(var x=0; x<settings.populationSize; x++){
for(var y=0; y<settings.forestSize; y++){
if(population.sheep[x].xpos==forest.trees[y].posx && population.sheep[x].ypos==forest.trees[y].posy){
forest.trees[y].posx=null;
forest.trees[y].posy=null;
population.sheep[x].state=1;
population.sheep[x].fitness++;
}
}
}
//move sheep based on chromosome
for(var x=0; x<settings.populationSize; x++){
var move = Math.random();
if(population.sheep[x].state==0){
switch(moveHungry(x, move)){
case 0: //up
if(population.sheep[x].ypos>0)
population.sheep[x].ypos-=1;
break;
case 1: //down
if(population.sheep[x].ypos<settings.rows-1)
population.sheep[x].ypos+=1;
break;
case 2: //right
if(population.sheep[x].xpos<settings.cols-1)
population.sheep[x].xpos+=1;
break;
case 3: //left
if(population.sheep[x].xpos>0)
population.sheep[x].xpos-=1;
}
}
else {
switch(moveEaten(x, move)){
case 0: //up
if(population.sheep[x].ypos>0)
population.sheep[x].ypos-=1;
break;
case 1: //down
if(population.sheep[x].ypos<settings.rows-1)
population.sheep[x].ypos+=1;
break;
case 2: //right
if(population.sheep[x].xpos<settings.cols-1)
population.sheep[x].xpos+=1;
break;
case 3: //left
if(population.sheep[x].xpos>0)
population.sheep[x].xpos-=1;
}
}
}
counter++;
}
function reset(){
counter=0;
//regrow forest
forest = new Forest(settings.forestSize);
//reset locations and fitness values
for(var x=0; x<settings.populationSize; x++){
population.sheep[x].xpos = Math.floor(Math.random()*settings.cols);
population.sheep[x].ypos = Math.floor(Math.random()*settings.rows);
population.sheep[x].fitness=0;
}
}
function setup() {
createCanvas(1000, 500);
}
function draw() {
createWorld();
if(counter>=settings.year){
population.evaluate();
population.breed();
reset();
generation++;
if(generation>=settings.end){
noLoop();
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.3/p5.min.js"></script>

Who to get the sum of two arrays?

I want to sum two arrays : num_array and num2_array using for loops like this for example : num_array[1] + num2_array[5], num_array[2] + num2_array[4] ...
This is what I've tried :
var num_array, num2_array;
var i, j, sum = 0;
for(i=0; i < 6; i++)
{
num_array[i] = get_integer("NUMBER: ","");
while(num_array[i] < 1 && num_array[i] > 500)
{
num_array[i] = get_integer("Enter a number inn limit of 1 to 500", 0);
}
}
for(i=5; i >= 0; i--)
{
num2_array[i] = num_array[i];
show_message(num2_array[i]);
}
Refer this code
var num_array,num2_array;
var sum=0;
for(var i=0;i<num_array.length,i++){
sum+=num_array[i]
}
for(var j=0;j<num2_array.length,j++){
sum+=num_array[j]
}

Create range of letters and numbers

I'm creating a form where users can input a range. They are allowed to input letters and numbers. Some sample input:
From: AA01
To: AZ02
Which should result in:
AA01
AA02
AB01
AB02
And so on, till AZ02
And:
From: BC01
To: DE01
Should result in:
BC01
BD01
BE01
CC01
CD01
CE01
Etc
I managed to get it working for the input A01 to D10 (for example)
jsFiddle
However, i can't get it to work with multiple letters.
JS code:
var $from = $('input[name="from"]');
var $to = $('input[name="to"]');
var $quantity = $('input[name="quantity"]');
var $rangeList = $('.rangeList');
var $leadingzeros = $('input[name="leadingzeros"]');
$from.on('keyup blur', function () {
$(this).val($(this).val().replace(/[^a-zA-Z0-9]/g, ''));
updateQuantity();
});
$to.on('keyup blur', function () {
$(this).val($(this).val().replace(/[^a-zA-Z0-9]/g, ''));
updateQuantity();
});
$leadingzeros.on('click', function () {
updateQuantity();
});
function updateQuantity() {
var x = parseInt($from.val().match(/\d+/));
var y = parseInt($to.val().match(/\d+/));
var xl = $from.val().match(/[a-zA-Z]+/);
var yl = $to.val().match(/[a-zA-Z]+/);
var result = new Array();
if (xl != null && yl != null && xl[0].length > 0 && yl[0].length > 0) {
xl = xl[0].toUpperCase();
yl = yl[0].toUpperCase();
$rangeList.html('');
var a = yl.charCodeAt(0) - xl.charCodeAt(0);
for (var i = 0; i <= a; i++) {
if (!isNaN(x) && !isNaN(y)) {
if (x <= y) {
var z = (y - x) + 1;
$quantity.val(z * (a + 1));
$rangeList.html('');
for (var b = z; b > 0; b--) {
var c = ((y - b) + 1);
if ($leadingzeros.prop('checked')) {
c = leadingZeroes(c, y.toString().length);
}
result.push(String.fromCharCode(65 + i) + c);
}
} else {
$rangeList.html('');
$quantity.val(0);
}
} else {
$rangeList.html('');
$quantity.val(0);
}
}
} else if (!isNaN(x) && !isNaN(y)) {
if (x < y) {
var z = (y - x) + 1;
$quantity.val(z);
$rangeList.html('');
for (var i = z; i > 0; i--) {
var c = (y - i) + 1;
if ($leadingzeros.prop('checked')) {
c = leadingZeroes(c, y.toString().length);
}
result.push(c);
}
} else {
$rangeList.html('');
$quantity.val(0);
}
} else {
$rangeList.html('');
$quantity.val(0);
}
$rangeList.html('');
for (var i = 0; i < result.length; i++) {
$rangeList.append(result[i] + '<br />');
}
}
function leadingZeroes(number, size) {
number = number.toString();
while (number.length < size) number = "0" + number;
return number;
}
This is perfect for a recursive algorithm:
function createRange(from, to) {
if (from.length === 0) {
return [ "" ];
}
var result = [];
var innerRange = createRange(from.substring(1), to.substring(1));
for (var i = from.charCodeAt(0); i <= to.charCodeAt(0); i++) {
for (var j = 0; j < innerRange.length; j++) {
result.push(String.fromCharCode(i) + innerRange[j]);
}
}
return result;
}
Called as follows:
createRange('BC01', 'DE02'); // Generates an array containing all values expected
EDIT: Amended function below to match new test case (much more messy, however, involving lots of type coercion between strings and integers).
function prefixZeroes(value, digits) {
var result = '';
value = value.toString();
for (var i = 0; i < digits - value.length; i++) {
result += '0';
}
return result + value;
}
function createRange(from, to) {
if (from.length === 0) {
return [ "" ];
}
var result = [];
if (from.charCodeAt(0) < 65) {
fromInt = parseInt(from);
toInt = parseInt(to);
length = toInt.toString().length;
var innerRange = createRange(from.substring(length), to.substring(length));
for (var i = fromInt; i <= toInt; i++) {
for (var j = 0; j < innerRange.length; j++) {
result.push(prefixZeroes(i, length) + innerRange[j]);
}
}
} else {
var innerRange = createRange(from.substring(1), to.substring(1));
for (var i = from.charCodeAt(0); i <= to.charCodeAt(0); i++) {
for (var j = 0; j < innerRange.length; j++) {
result.push(String.fromCharCode(i) + innerRange[j]);
}
}
}
return result;
}
Please note that because of your strict logic in how the value increments this method requires exactly 4 characters (2 letters followed by 2 numbers) to work. Also, this might not be as efficient/tidy as it can be but it took some tinkering to meet your logic requirements.
function generate(start, end) {
var results = [];
//break out the start/end letters/numbers so that we can increment them seperately
var startLetters = start[0] + start[1];
var endLetters = end[0] + end[1];
var startNumber = Number(start[2] + start[3]);
var endNumber = Number(end[2] + end[3]);
//store the start letter/number so we no which value to reset the counter to when a maximum boundry in reached
var resetLetter = startLetters[1];
var resetNumber = startNumber;
//add first result as we will always have at least one
results.push(startLetters + (startNumber < 10 ? "0" + startNumber : "" + startNumber));
//maximum while loops for saefty, increase if needed
var whileSafety = 10000;
while (true) {
//safety check to ensure while loop doesn't go infinite
whileSafety--;
if (whileSafety == 0) break;
//check if we have reached the maximum value, if so stop the loop (break)
if (startNumber == endNumber && startLetters == endLetters) break;
//check if we have reached the maximum number. If so, and the letters limit is not reached
//then reset the number and increment the letters by 1
if (startNumber == endNumber && startLetters != endLetters) {
//reset the number counter
startNumber = resetNumber;
//if the second letter is at the limit then reset it and increment the first letter,
//otherwise increment the second letter and continue
if (startLetters[1] == endLetters[1]) {
startLetters = '' + String.fromCharCode(startLetters.charCodeAt(0) + 1) + resetLetter;
} else {
startLetters = startLetters[0] + String.fromCharCode(startLetters.charCodeAt(1) + 1);
}
} else {
//number limit not reached so just increment the number counter
startNumber++;
}
//add the next sequential value to the array
results.push(startLetters + (startNumber < 10 ? "0" + startNumber : "" + startNumber));
}
return results;
}
var results = generate("BC01", "DE01");
console.log(results);
Here is a working example, which uses your second test case
Using #Phylogenesis' code, i managed to achieve my goal.
jsFiddle demo
function updateQuantity() {
var x = parseInt($from.val().match(/\d+/));
var y = parseInt($to.val().match(/\d+/));
var xl = $from.val().match(/[a-zA-Z]+/);
var yl = $to.val().match(/[a-zA-Z]+/);
var result = new Array();
var r = createRange(xl[0], yl[0]);
var z = (y - x) + 1;
if (x <= y) {
for (var j = 0; j < r.length; j++) {
var letters = r[j];
for (var i = z; i > 0; i--) {
var c = (y - i) + 1;
if ($leadingzeros.prop('checked')) {
c = leadingZeroes(c, y.toString().length);
}
if (i == z) {
r[j] = letters + c + '<br />';
} else {
j++;
r.splice(j, 0, letters + c + '<br />');
}
}
}
} else {
for (var i = 0; i < r.length; i++) {
r[i] += '<br />';
}
}
$quantity.val(r.length);
$rangeList.html('');
for (var i = 0; i < r.length; i++) {
$rangeList.append(r[i]);
}
}
This works for unlimited letters and numbers, as long as the letters are first.
Thanks for your help!

How to modify this function to return string instead of int

please take a quick look at this function that I have found on the web.
function longestCommonSubstring(string1, string2){
// init max value
var longestCommonSubstring = 0;
// init 2D array with 0
var table = Array(string1.length);
for(a = 0; a <= string1.length; a++){
table[a] = Array(string2.length);
for(b = 0; b <= string2.length; b++){
table[a][b] = 0;
}
}
// fill table
for(var i = 0; i < string1.length; i++){
for(var j = 0; j < string2.length; j++){
if(string1[i]==string2[j]){
if(table[i][j] == 0){
table[i+1][j+1] = 1;
} else {
table[i+1][j+1] = table[i][j] + 1;
}
if(table[i+1][j+1] > longestCommonSubstring){
longestCommonSubstring = table[i+1][j+1];
}
} else {
table[i+1][j+1] = 0;
}
}
}
return longestCommonSubstring;
}
It returns the length of the longest common substring as an int. Now to my question, is it possible to modify this function, so that it returns the actual string instead of just returning the length of the substring, I'm quite new at programming and thought that just modifying this secetion would help if(string1[i]==string2[j]){ push(string1[i]}, but it isn't that easy, because I don't want every single character that is the same in those 2 strings to be added in that array, only those that are exactly the same.
Thanks in advance =)
Well for minimal changes to the existing function you could declare a new variable:
var theCommonString = '';
Then in the middle of the function add a line after this existing one:
longestCommonSubstring = table[i+1][j+1];
that says something like:
theCommonString = string1.substr(i + 1 - longestCommonSubstring,
longestCommonSubstring);
(That i + 1 index may be a little off, I haven't bothered working it out carefully.)
Then at the end just return your new variable instead of the existing one.
Note that if there is more than one common sub string of the same length this will return the last one.
You can just store the whole common substring in the table instead of its length:
function longestCommonSubstring(string1, string2){
// init max value
var longestCommonSubstring = "";
// init 2D array with 0
var table = Array(string1.length);
for(a = 0; a <= string1.length; a++){
table[a] = Array(string2.length);
for(b = 0; b <= string2.length; b++){
table[a][b] = 0;
}
}
// fill table
for(var i = 0; i < string1.length; i++){
for(var j = 0; j < string2.length; j++){
if(string1[i]==string2[j]){
if(table[i][j] == 0){
table[i+1][j+1] = string1[i];
} else {
table[i+1][j+1] = table[i][j] + string1[i];
}
if(table[i+1][j+1].length > longestCommonSubstring.length){
longestCommonSubstring = table[i+1][j+1];
}
} else {
table[i+1][j+1] = 0;
}
}
}
return longestCommonSubstring;
}

Categories

Resources