# Write a function called get_distance that accepts two character vector inputs representing the names of two cities. The function returns the distance between them as an output argument called distance. For example, the call get_distance('Seattle, WA'

42 views (last 30 days)

Show older comments

function distance = get_distance(x,y)

[~,~,raw] = xlsread('Distances.xlsx');

col_labels = raw(1,:);

row_labels = raw(:,1);

try

distance = raw{contains(row_labels,y),contains(col_labels,x)};

catch

distance = -1;

end

end

error

Assessment result: incorrectNashville, TN and Las Vegas, NV

Variable distance has an incorrect value.

Assessment result: incorrectRandom city pairs

Variable distance has an incorrect value.

get_distance('Chattanooga, TN','Meads, KY') returned -1 which is incorrect.

##### 0 Comments

### Answers (22)

Arafat Roney
on 6 May 2020

function distance=get_distance(a,b)

[~,~,raw]=xlsread('Distances.xlsx');

row=raw(1,:);

col=raw(:,1);

for ii=2:length(row)

if strcmp(row(ii),a)

mii=ii;

break;

end

end

for jj=2:length(col)

if strcmp(col(jj),b)

njj=jj;

break;

end

end

if (strcmp(row(ii),a))&&(strcmp(col(jj),b))

distance=raw{mii,njj};

else

distance=-1;

end

end

##### 6 Comments

SOUMYAJIT MONDAL
on 20 Aug 2021

Okay ,

if raw(1,;) represents the first row of that cell array then row=raw(,;) should also be selecting the first row. So 'row' is not initialised as a vector ,but in the for loop 'row' is used as a vector ex. row(1) , row(2), ....

Walter Roberson
on 20 Aug 2021

Mati Somp
on 6 Oct 2020

one more

function distance = get_distance(A,B)

[data txt] =xlsread('Distances.xlsx');

ii=0;

jj=0;

for i=2:length(data)

if string(A)==string(txt{1,i})

ii=i;

end

if (string(B)==string(txt{1,i}))

jj=i;

end

end

if (~(jj) || ~(ii))

distance=-1;

else

distance=data(ii-1,jj-1);

end

##### 2 Comments

Kulko Margarita
on 12 Feb 2021

Olel Arem
on 1 May 2020

Edited: Olel Arem
on 1 May 2020

function distance=get_distance(city_1,city_2)

n=0;m=0;

[value,name]=xlsread('Distances.xlsx');

for ii=1:size(name,2)

if (strcmp(city_1,name(ii,1)))

n=ii;

end

end

for jj=1:size(name,1)

if (strcmp(city_2,name(1,jj)))

m=jj;

end

end

if(n==0 && m==0 && n==1&&m==1)

distance =-1;

elseif (n>0&&m>0)

distance=value(n-1,m-1);

else

distance=-1;

end

##### 2 Comments

Syed Zubair shah
on 16 Mar 2022

if(n==0 && m==0 && n==1&&m==1)

can you explain why we use this line and kindly explain it

Rik
on 16 Mar 2022

Taif Ahmed BIpul
on 28 May 2020

function distance=get_distance(A,B)

[~,~,All]=xlsread('Distances.xlsx');

p=strcmp(All,A);

q=strcmp(All,B);

r=sum(p(:));

s=sum(q(:));

if ~(r==2&&s==2)

distance=-1;

return

end

a=find(p==1);

b=find(q==1);

distance=All{(a(1)),(b(1))};

##### 2 Comments

Nada Hussein
on 20 Jul 2020

Edited: Nada Hussein
on 20 Jul 2020

can you please explain your code? i don't get the lines:5,6,7,11,12

Walter Roberson
on 20 Jul 2020

The ==2 does not make sense to me; it would make sense to me if it were ==1 meaning that exactly one column matched.

Oh wait... the Raw (third) output has the names in the first row and in the first column. The person who wrote the above code assumes that each name will appear exactly once in the header row and once in the header column, for a total of two appearances: that is why the 2. The person also assumes that the order is exactly the same between the rows and columns.

Distance matrices should not be assumed to be symmetric. I would not recommend this version of the code.

UJJWAL Padha
on 11 Jun 2020

function distance = get_distance(x,y)

k=-1;

[~,~,all] = xlsread('Distances.xlsx');

[r c] = size(all)

for i = 1:r

for j = 1:c

if i==1 && j==1

continue;

else

if strcmp(x,all(i,1))==1 && strcmp(y,all(1,j))==1

k= all{i,j};

end

end

end

end

distance = k;

end

##### 2 Comments

Rik
on 1 Sep 2020

Ankit singh chauhan
on 29 Nov 2020

Edited: Rik
on 29 Nov 2020

function distance=get_distance(city1,city2) [~,~,raw]=xlsread('Distance.xlsx') try s=strcmp(raw,city2)

g=strcmp(raw,city1)

[r1,c1]=find(s==1)

[r2,c2]=find(g==2)

distance=raw{r1,r2}

catch

distance=-1

end

##### 1 Comment

Gokul surya Subramanian
on 17 Apr 2019

Edited: Rik
on 2 Jul 2019

function distance = get_distance(a,b)

[~,text,raw] = xlsread('Distances.xlsx');

for i=2:size(raw,1)

if strcmp(text{i,1}, a)

break

end

end

if i>=size(raw,1)

distance=-1;

else

for j=2:size(raw,2)

if strcmp(text{1,j}, b)

distance=raw{i,j};

break

end

end

if j>=size(raw,2)

distance = -1;

end

end

##### 13 Comments

Walter Roberson
on 17 Feb 2021

For this particular homework problem, the reference data has been defined to be stored in a xlsx file that has the format

<empty> <cityname1> <cityname2> <cityname3> ...

<cityname1> distance11 distance12 distance13 ...

<cityname2> distance21 distance22 distance23 ...

where the <cityname> are text such as 'Los Vegas, Nevada' and 'Wawa, Ontario', and the distances are numeric.

When you use xlsread on the file and ask for the second output, the output will be a cell array of character vectors, with the character vectors being present where the original data had text, and being empty where the original data had numbers. So it might look something like

txt = {

[], 'LA', 'Wawa', 'Lima'

'LA' [] [] []

'Wawa' [] [] []

'Lima' [] [] []

}

When you use txt{1,i} you would therefore be accessing the [] at the beginning, or one of the city names, 'LA', 'Wawa', 'Lima' -- you would be reading out of row #1 from the txt cell array. txt{ROWNUMBER, COLUMNNUMBER} is the general form.

Using string() on a character vector converts it from being a character vector to being a scalar "string" object. So the line

if string(A)==string(txt{1,i})

converts character vector inside A to a string() object; and then extracts the content of column #i from row 1 of the cell array named txt and converts that content into a string() object. Then the line uses == between the string objects.

The reason someone would do that is that == is defined between string objects to return true of the strings have the same content, and false if the strings do not have the same content, with false being returned if they are different because they have different lengths. So string('LA') == string('Wawa') is perfectly good code that will not have a problem.

But == is not defined between character vectors in the same way, In particular, == between character vectors will fail if they both have more than one character and the lengths do not match. 'LA'=='Wawa' would fail complaining that the array dimensions do not agree (meaning that the lengths are different.) To compare character vectors taking into account they might be different lengths, use strcmp(), as in strcmp('LA', 'Wawa')

Muhammad Sadiq
on 7 May 2020

function distance = get_distance(a,b)

[~,text,raw] = xlsread('Distances.xlsx');

for i=2:size(raw,1)

if strcmp(text{i,1}, a)

break

end

end

if i>=size(raw,1)

distance=-1;

else

for j=2:size(raw,2)

if strcmp(text{1,j}, b)

distance=raw{i,j};

break

end

end

if j>=size(raw,2)

distance = -1;

end

end

##### 0 Comments

Alan Chacko
on 13 May 2020

function d = get_distance(c1,c2)

[~,~,city] = xlsread("Distances.xlsx");

[r,c] = size(city);

row = city(1:end,1);

col = city(1,1:end);

ccr=sort(contains(row(2:end),c1));

ccc=sort(contains(col(2:end),c2));

if ccr'==ccc

ir = find(strcmp(row,c1));

ic = find(strcmp(col,c2));

d = city{ir,ic};

else

d=-1;

end

##### 5 Comments

Walter Roberson
on 31 May 2020

What happens when you use the debugger to trace the flow of your code?

Timothy Simon Thomas
on 21 May 2020

function distance=get_distance(L1,L2)

[n,~,r]=xlsread('matlab_dist.xlsx');

i=1;j=1;

[R C]=size(n);

while(~(strcmp(L1,r(1,i))) && i<=R)

i=i+1;

end

while(~(strcmp(L2,r(j,1)))&& j<=C)

j=j+1;

end

j=j-1;i=i-1;

if(~(strcmp(L1,r(1,i+1))) || ~(strcmp(L2,r(j+1,1))))

distance=-1;

else

distance=n(i,j);

end

end

##### 0 Comments

Ujjawal Barnwal
on 7 Jun 2020

function distance=get_distance(c1,c2)

[num txt raw]=xlsread("Distances.xlsx");

a=0;b=0;

for ii=2:337

if strcmp(txt{1,ii},c1)

a=ii;

elseif strcmp(txt{1,ii},c2)

b=ii;

end

end

if a && b

distance=num(a-1,b-1);

else

distance=-1;

end

##### 1 Comment

Walter Roberson
on 7 Jun 2020

Why 337?

Your code assumes that Distances contains data of a particular size. It also assumes that the number of rows and columns is the same. It further assumes that there is never a case where the two different cities happen to occur at the same row and column number. For example,

* apple orange grapefruit

orange 2 0 3

grapefruit 1 3 0

apple 0 2 1

Your code would fail for (say) orange, grapefruit because it assumes that when it finds orange in column 3, that it is not possible to also happen to find grapefruit in row 3.

Vishesh Haria
on 7 Jun 2020

function distance=get_distance(a,b)

[~,~,raw]=xlsread('Distances.xlsx');

row=raw(1,:);

col=raw(:,1);

for ii=2:length(row)

if strcmp(row(ii),a)

mii=ii;

break;

end

end

for jj=2:length(col)

if strcmp(col(jj),b)

njj=jj;

break;

end

end

if(njj > 0 && mii > 0)

distance = raw{mii,njj};

elseif(njj == 1 && mii == 1)

distance = -1;

elseif(njj == 0 && mii == 0)

distance = -1;

else

distance=-1;

end

end

Error:

distance = get_distance('g, WA','Miagmi, FL')

Unrecognized function or variable 'njj'.

Error in get_distance (line 19)

if(njj > 0 && mii > 0)

Help me understand this error.

##### 1 Comment

亮 张
on 24 Jun 2020

Md Nazmus Sakib
on 20 Jun 2020

function y = get_distance(city_1,city_2)

global raw;

[~,~,raw] = xlsread('Distances.xlsx');

%fetching cities in rows

r_city = {};

for i = 1:337

r_city{1,i} = raw{1,i};

end

%fetching cities in columns

c_city = {};

for j = 1:337

c_city{1,j} = raw{j,1};

end

%searching city_1

search_c1 = strcmp(c_city,city_1);

%searching row

for ii = 1:337

if (search_c1(1,ii) == 1)

break

else

ii = 1;%if the city is not found ii will give 1

end

end

%searching city_2

search_c2 = strcmp(r_city,city_2);

%searching column

for jj = 1:337

if (search_c2(1,jj) == 1)

break

else

jj = 1;%if the city is not found jj will give 1

end

end

if ((ii == 1) || (jj == 1)) % if the city is not found

y = -1;

else

y = raw{ii,jj}(1,1);

end

end

##### 2 Comments

Walter Roberson
on 20 Jun 2020

What will you do when the Distances.xlsx file does not have exactly 337 rows and columns ?

M NAGA JAYANTH AVADHANI
on 28 Jul 2020

Edited: M NAGA JAYANTH AVADHANI
on 28 Jul 2020

This works perfectly.

function distance = get_distance(city1,city2)

[~,~,raw] = xlsread('Distances.xlsx');

row = raw(1,:);

col = raw(:,1);

mi =0;mj =0;

for i = 2:length(row)

if strcmp(row(i),city1)

mi = i;

end

end

for j = 2:length(col)

if strcmp(col(j),city2)

mj = j;

end

end

if mi> 1 && mj>1

distance = raw{mi,mj};

else

distance = -1;

end

end

##### 3 Comments

Rik
on 14 Aug 2020

Capulus_love
on 12 Aug 2020

Edited: Capulus_love
on 12 Aug 2020

function distance = get_distance(a,b)

[~,~,excel] = xlsread('Distances.xlsx');

col = excel(1,:);

row = excel(:,1);

x=size(col)

y=size(row)

col_count = 1;

row_count = 1;

for i = 2 : x(2)+1

col_count = col_count + 1;

if contains(col{i},a) == 1

break

end

end

for j = 2 : y(1)+1

row_count = row_count + 1;

if contains(row{j},b) == 1

break

end

end

if (col_count > 337) || (row_count > 337)

distance = -1

else

distance = excel{row_count,col_count}

end

end

% why Non-existent city is not solved...???

##### 3 Comments

Rik
on 12 Aug 2020

Where are you checking if a city exists in the list? What happens on each line if that happens?

Walter Roberson
on 12 Aug 2020

if (col_count > 337) || (row_count > 337)

What would happen if they changed the data file to one that had (for example) 500 cities?

Yan Li
on 4 Sep 2020

function distance = get_distance (ct1, ct2)

[~,~,raw]= xlsread("Distances.xlsx");

f_row = raw(1,:);

f_col = raw(:,1);

flag = false;

distance = -1;

for n=1:length(f_row)

for m=1:length(f_col)

if string(f_row(n)) == ct1 && string(f_col(m)) == ct2

flag = true

distance = raw{n,m};

end

end

end

end

##### 2 Comments

Rik
on 4 Sep 2020

Surprisingly enough this works.

string({'foo'})=='foo'

Why did you decide to post this? What does it teach?

Also, why are you setting a flag, but not returning it or using it anywhere?

Ahmed Saleh
on 28 Mar 2021

Edited: Ahmed Saleh
on 28 Mar 2021

function distance = get_distance(city1,city2)

[~,~,distances] = xlsread('Distances.xlsx');

num1=0;

num2=0;

s=size(distances);

for i=2:s(1)

logic=strcmp(city1,distances{i,1});

if logic== true

num1=i;

break

end

end

for j=2:s(2)

logic2 = strcmp(city2,distances{1,j});

if logic2 == true

num2=j;

break

end

end

if num1==0 || num2==0

distance=-1;

return

end

distance=distances{num1,num2};

end

##### 7 Comments

Rik
on 29 Mar 2021

You mean that one? You can use it to attract the attention of high reputation users and site administrators to solve a particular issue (e.g. if a post should be deleted or a thread should be closed).

Also, strcmp doesn't just return 1 or 0, it returns true or false. And it doesn't always return 1 value.

To refrase Walter's second question: when is false equal to true or is true not equal to true?

Use the debugger to execute your code line by line.

Abhijeet Singh
on 14 May 2021

Edited: Abhijeet Singh
on 14 May 2021

function distance = get_distance(x,y)

[~,~,everything] = xlsread('Distances.xlsx');

a = everything(1:size(everything,1),1);

b = everything(1,1:size(everything,2));

for j = 1:size(everything,1)

l=0;

if strcmp(a(j,1),x)

l=j;

break

end

end

for i = 1:size(everything,2)

k=0;

if strcmp( b(1,i),y)

k=i;

break

end

end

if k ~= 0 && l ~= 0

s = everything(l,k);

distance = s{1};

else

distance = -1;

end

end

##### 3 Comments

Abhijeet Singh
on 15 May 2021

Rik
on 15 May 2021

What would you say is the key difference between your solution and the one above this one?

If you want to educate: comments are a great way to explain what your code is doing.

Also:

a = everything(1:size(everything,1),1);

b = everything(1,1:size(everything,2));

%is equivalent to this:

a = everything(:,1);

b = everything(1,:);

Silvana Castillo
on 3 Jun 2021

function distance = get_distance(c1,c2);

% reads excel file in just everything

[~,~,everything] = xlsread('Distances.xlsx');

% find would give index of c1 readinf first column

a = find(strcmp(everything(1,1:end),c1))

% find would give index of c2 reading first row

% strcmp = are equals two strings inputs?

b = find(strcmp(everything(1:end,1),c2))

% if any c1 or c2 do not exist

if isempty(a) || isempty(b)

distance = -1

else

% converts from cell class to matrix or double

%the distance value based on index

distance = cell2mat(everything(a,b))

end

##### 0 Comments

Milad Mehrnia
on 31 Oct 2021

function distance = get_distance(a,b)

[num,txt] = xlsread('Distances.xlsx');

x = 0;y = 0;

for i = 2:lenghth(txt)

if strcmp(txt{1,i},a)

x = i;break; % It's better to use break, Because it reduces the running time significantly

end

end

for j = 2:height(txt) % It's better to use a seperated for function for j, Because it reduces the running time significantly too

if strcmp(txt{j,1},b)

y = j;break;

end

end

if ~x || ~y

distance = -1;

else

distance = num(x-1,y-1);

end

##### 2 Comments

Rik
on 1 Nov 2021

You are on the right track. I would suggest looking up the numel and size functions (as replacement for height and length, which you misspelled).

I would also suggest looking up ismember, which can further increase performance.

Milad Mehrnia
on 1 Nov 2021

As we have the matrices on the memory, you are right and ismember is better than for. After your comment I tried it and the result is awesome. It brakes the time to half.

Really thank you

Zia Ur Rehman
on 30 Aug 2022

Hi folks,

plz check my code and plz tell me if I can improve this.

function distance = get_distance(a,b)

[~, ~, data] = xlsread('Distances.xlsx'); %reading the file and having its full data that is by default raw data in data variable on 3rd aurgument

z = size(data); % Calculating the size as we need to traverse both first coloumn and first row

c = z(1,1); % c = no. of rows

d = z(1,2); % d = no. of coloumn

for i = 2:c % as (1,1) of file is empty so starting from 2 to the length of rows and coloumns

e = strcmp(data{1,i},a); % checking through first row and compare with a

if e == true % if we find the matching then record its index in f and stop the loop through 'break'.

f = i;

break;

end

end

for j = 2:d

k = strcmp(data{j,1},b); % checking through first coloumn and compare with b

if k == true % if we find the matching then record its index in l and stop the loop through 'break'.

l = j;

break;

end

end

if e==true && k==true % if both are true then show the distance at that index(f,l) otherwisr distance = -1

distance = data{f,l};

else

distance = -1;

end

##### 4 Comments

Pascal
on 15 Jun 2023

I got this solution but the last bit of code seems rather plump, do you have suggestions to improve the code?

function [distance] = get_distance(c1,c2)

raw = readcell('Distances.xlsx');

row1 = raw(1,2:end);

col1 = raw(2:end,1);

ind1 = find(ismember(row1,c1));

ind2 = find(ismember(col1,c2));

if isempty(ind1) || isempty(ind2)

distance = -1;

else

dis = raw(2:end,2:end);

d = dis(ind1,ind2);

distance = cell2mat(d);

end

##### 0 Comments

### See Also

### Categories

### Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!