예제 #1
0
파일: lsh_distance.c 프로젝트: agrbin/msa
struct lsh_iterator*
lsh_initialize(int len1, int len2, int(*penalty_)(int, int),
    int bandwidth, int *result)
{
  struct lsh_iterator* ret;
  assert (!busy);
  busy = 1;
  n1 = len1 + 1, n2 = len2 + 1;
  /* this is ugly comunication between lsh_initialize_mcmp and lsh_initialize
   * to check if we have mpenalty
   */
  if (bandwidth < 0) {
    bandwidth *= -1;
  } else {
    mpenalty = NULL;
    mmpenalty = NULL;
  }
  penalty = penalty_;
  K = bandwidth;
  adjust_bandwidth();
  double_K_plus_1 = 2*K + 1;
  check_allocation();
  edit_distance();
  output();
  if (result != NULL) {
    *result = dp_read[n2 - n1 + K];
  }
  ret = (struct lsh_iterator*) malloc(sizeof(struct lsh_iterator));
  ret->_row = n1 - 1;
  ret->_col = n2 - n1 + K;
  return ret;
}
void checkSpell(std::string wrong)
{
	std::vector<std::string> temp;
	splitStr(wrong, &temp);
	for (int i = 0;i < temp.size();++i)
	{
		std::ifstream myIf("CT2 dict.txt");
		std::string data;
		while (!myIf.eof())
		{
			myIf >> data;
			int distance = edit_distance(temp[i], data);
			if (distance == 0)
			{
				continue;
			}
			else
			if (distance == 1)
			{
				temp[i] = temp[i] + " (" + data + ')';
			}
		}
	}
	std::string result;
	for (int i = 0;i < temp.size() - 1;++i)
	{
		result = result + temp[i] + ' ';
	}
	result = result + temp[temp.size() - 1] + '.';
	std::cout << result << '\n';
}
예제 #3
0
파일: distcorr.c 프로젝트: jttkim/lindevol
int distcorr(FILE *outfile, long generation)
{
  long i, j, editdist;
  double treedist;

  for (i = 0; i < psize; i++)
  {
    for (j = 0; j < i; j++)
    {
      treedist = phyl_leafdistance(&phyltree, seq[i].name, seq[j].name);
      if (treedist < 0.0)
      {
        fprintf(stderr, "distcorr: error #%f determining tree distance between %s and %s\n", treedist, seq[i].name, seq[j].name);
        continue;
      }
      editdist = edit_distance(seq[i].genome.length, seq[i].genome.g,
              seq[j].genome.length, seq[j].genome.g);
      if (editdist < 0)
      {
        fprintf(stderr, "distcorr: error #%ld determining edit distance between %s and %s\n", editdist, seq[i].name, seq[j].name);
        continue;
      }
      fprintf(outfile, "%f %ld\n", treedist, editdist);
    }
  }
  for (i = 0; i < psize; i++)
    free_genome(&(seq[i].genome));
  free(seq);
  phyl_free_tree(&phyltree);
  return (0);
}
예제 #4
0
int FusionMapper::calcED(string seq, int contig, int start, int end) {
    // check start and end are in same strand
    if( (start>=0 && end<=0) || (start<=0 && end>=0) ) {
        return -1;
    }

    string& fusionSeq = mIndexer->mFusionSeq[contig];

    // check the overflow
    if(abs(start)>=fusionSeq.length() || abs(end)>=fusionSeq.length())
        return -2;

    string str = seq;
    if(start < 0) {
        Sequence s(seq);
        Sequence rc = ~s;
        str = rc.mStr;

        int tmp = start;
        start = -end;
        end = -tmp;
    }

    string refstr = fusionSeq.substr(start, end-start+1);

    return edit_distance(str.c_str(), str.length(), refstr.c_str(), refstr.length());
}
예제 #5
0
파일: similarity.cpp 프로젝트: joto/taginfo
/**
 * Are the two given strings similar according to some metric?
 */
int similarity(const char* str1, int len1, const char* str2, int len2) noexcept {
    // Do not check very short strings, because they create too many false
    // positives.
    if (len1 < MIN_STRLEN || len2 < MIN_STRLEN) {
        return -1;
    }

    // Do not check very long strings. This keeps memory use and run time for
    // Levenshtein algorithm in check.
    if (len1 >= MAX_STRLEN || len2 >= MAX_STRLEN) {
        return -1;
    }

    // Check if one string is a substring of the other. This will also check
    // if both strings differ only in case.
    if (strcasestr(str1, str2) || strcasestr(str2, str1)) {
        return 0;
    }

    // Do not check strings if they have very different lengths, they can't
    // be similar according to Levenshtein anyway.
    if (std::abs(len1 - len2) >= MAX_EDIT_DISTANCE) {
        return -1;
    }

    // Check Levenshtein edit distance.
    const int distance = edit_distance(str1, len1, str2, len2);
    if (distance <= MAX_EDIT_DISTANCE) {
        return distance;
    }

    return -1;
}
예제 #6
0
파일: dmt_file.c 프로젝트: jttkim/lindevol
void write_dmt(void)
{
  long i, j;
  short d;

  fprintf(dmt_file, "%ld\r\n", psize);
  fprintf(dmt_file, "%ld\r\n", generation);
  j = 0;
  for (i = 0; i < world_width; i++)
  {
    if (plant[i] != NULL)
    {
      tmp_index[j++] = i;
    }
  }
  for (i = 0; i < psize - 1; i++)
  {
    for (j = i + 1; j < psize; j++)
    {
      d = (short) edit_distance(plant[tmp_index[i]]->genome.length, (char *) plant[tmp_index[i]]->genome.g,
                                plant[tmp_index[j]]->genome.length, (char *) plant[tmp_index[j]]->genome.g);
      fwrite_int16array(&d, 1, dmt_file);
    }
  }
  fflush(dmt_file);
}
예제 #7
0
파일: edit_distance.c 프로젝트: kopos/kata
///
// Version 1
///
int edit_distance(char *s1, char *s2, uint l1, uint l2) {
    if (l1 == 0) { return (int) l2 * del(' '); }
    if (l2 == 0) { return (int) l1 * ins(' '); }

#ifdef DEBUG
    printf("%.*s, %.*s\n", l1, s1, l2, s2);
#endif
    int c1 = edit_distance(s1, s2, l1 - 1, l2) + ins(s1[l1]);
    int c2 = edit_distance(s1, s2, l1, l2 - 1) + del(s2[l2]);
    int c3 = edit_distance(s1, s2, l1 - 1, l2 - 1) + match(s1[l1], s2[l2]);
    int c = min3(c1, c2, c3);
#ifdef DEBUG
    printf("edit_distance(%.*s, %.*s) = %d\n", l1, s1, l2, s2, c);
#endif

    return c;
}
예제 #8
0
int main()
{
int t;
for(scanf("%d",&t);t--;)
{
scanf("%s",string1);
scanf("%s",string2);
printf("%d\n",edit_distance(strlen(string1),strlen(string2)));
}
return 0;
}
예제 #9
0
main(){
	
    //char Y[50] = "ATCGGTATC";
    //char X[50] = "ATGAATCGT";

    char Y[50] = "TRACEBACK";
	char X[50] = "BACKTRACK";
	printf("point1");
	printf("point2\n");
	edit_distance(X,Y,0,9,0,9);
	printf("done");
}
예제 #10
0
int main()
{
        char a[MAX_LEN];
        char b[MAX_LEN];

        scanf("%s", a);
        scanf("%s", b);

        int dis = edit_distance(a, strlen(a), b, strlen(b));

        printf("Edit Distance: %d\n", dis);

        return 0;
}
예제 #11
0
int main(int argc, char **argv)
{
	if (argc < 3) {
		usage(argc, argv);
		return 0;
	}
	
	char *word1 = argv[1];
	char *word2 = argv[2];
	//dump(word1, word2, m);
	int distance = edit_distance(word1, word2);
	printf("%d\n", distance);
	return 0;
}
예제 #12
0
vector<char> predict(const string& chain_code,const vector<Train>& trains){
    LOGD("predict start");
    vector<char> probabilities;
    probabilities.clear();

    int cost = edit_distance(chain_code,trains[0].path);
    LOGD("predict prob before");
    probabilities.push_back(trains[0].label);
    LOGD("predict prob after");
    for(int i = 1; i < (int) trains.size(); i++){
        LOGD("%d",i);
        int cnow = edit_distance(chain_code,trains[i].path);
        if (cnow < cost){
            cost = cnow;
            probabilities.clear();
            probabilities.push_back(trains[i].label);
        } else if (cnow == cost){
            probabilities.push_back(trains[i].label);
        }
    }
    LOGD("predict end");
    return probabilities;
}
예제 #13
0
int
main(void)
{

	printf("Please enter string 1: ");

	char *s1 = GetString();

	printf("Please enter string 2: ");

	char *s2 = GetString();

	printf("The edit distance is: %d\n", edit_distance(s1, s2));

}
예제 #14
0
파일: api.c 프로젝트: dgibson/ccan
int main(void)
{
	plan_tests(89);

	test_lcs();
	test_lev();
	test_rdl();
	test_dl();

	/* Unsupported edit distance measure */
	enum ed_measure badmeasure = (enum ed_measure)-1;
	ok1(edit_distance("ab", 2, "ba", 2, badmeasure) == (ed_dist)-1);

	return exit_status();
}
예제 #15
0
    Calculates Levenshtein's edit distance between strings \"a\" and \"b\"\n");

static PyObject *
editdist_distance(PyObject *self, PyObject *args)
{
	char *a, *b;
	int alen, blen, r;

	if (!PyArg_ParseTuple(args, "s#s#", &a, &alen, &b, &blen))
                return NULL;
	r = edit_distance(a, alen, b, blen);
	if (r == -1) {
		PyErr_SetString(PyExc_MemoryError, "Out of memory");
		return NULL;
	}
	return PyInt_FromLong(r);
}
예제 #16
0
/**
 * [FuzzyFilter::rank_find rank the result of the FuzzyFilter::find using edit distance]
 * @param  source  [str1]
 * @param  targets [target strings]
 * @param  f       [function that filter the strings, such as to_lower_case()]
 * @return         [vector of matched strings sorted by edit distance]
 */
FuzzyFilter::VecRankResult FuzzyFilter::rank_find( const String &source,
                                                   const VecString &targets,
                                                   String (*f)(const String &)
                                                 ) const
{
	VecRankResult results;

	VecString matches = find(source, targets, f);

	for(int i=0; i<matches.size(); i++)
	{
		int disance = edit_distance(f(source), f(matches[i]));

		results.push_back(RankResult(matches[i], disance));
	}

	std::sort(results.begin(), results.end());

	return results;
}
예제 #17
0
int hardsubx_process_frames_linear(struct lib_hardsubx_ctx *ctx, struct encoder_ctx *enc_ctx)
{
	// Do an exhaustive linear search over the video
	int got_frame;
	int dist;
	int cur_sec,total_sec,progress;
	int frame_number = 0;
	int64_t begin_time = 0,end_time = 0,prev_packet_pts = 0;
	char *subtitle_text=NULL;
	char *prev_subtitle_text=NULL;

	while(av_read_frame(ctx->format_ctx, &ctx->packet)>=0)
	{
		if(ctx->packet.stream_index == ctx->video_stream_id)
		{
			frame_number++;

			//Decode the video stream packet
			avcodec_decode_video2(ctx->codec_ctx, ctx->frame, &got_frame, &ctx->packet);

			if(got_frame && frame_number % 25 == 0)
			{
				float diff = (float)convert_pts_to_ms(ctx->packet.pts - prev_packet_pts, ctx->format_ctx->streams[ctx->video_stream_id]->time_base);
				if(abs(diff) < 1000*ctx->min_sub_duration) //If the minimum duration of a subtitle line is exceeded, process packet
					continue;

				// sws_scale is used to convert the pixel format to RGB24 from all other cases
				sws_scale(
						ctx->sws_ctx,
						(uint8_t const * const *)ctx->frame->data,
						ctx->frame->linesize,
						0,
						ctx->codec_ctx->height,
						ctx->rgb_frame->data,
						ctx->rgb_frame->linesize
					);


				// Send the frame to other functions for processing
				if(ctx->subcolor==HARDSUBX_COLOR_WHITE)
				{
					subtitle_text = _process_frame_white_basic(ctx,ctx->rgb_frame,ctx->codec_ctx->width,ctx->codec_ctx->height,frame_number);
				}
				else
				{
					subtitle_text = _process_frame_color_basic(ctx, ctx->rgb_frame, ctx->codec_ctx->width,ctx->codec_ctx->height,frame_number);
				}
				_display_frame(ctx, ctx->rgb_frame,ctx->codec_ctx->width,ctx->codec_ctx->height,frame_number);

				cur_sec = (int)convert_pts_to_s(ctx->packet.pts, ctx->format_ctx->streams[ctx->video_stream_id]->time_base);
				total_sec = (int)convert_pts_to_s(ctx->format_ctx->duration, AV_TIME_BASE_Q);
				progress = (cur_sec*100)/total_sec;
				activity_progress(progress,cur_sec/60,cur_sec%60);

				if(subtitle_text==NULL)
					continue;
				if(!strlen(subtitle_text))
					continue;
				char *double_enter = strstr(subtitle_text,"\n\n");
				if(double_enter!=NULL)
					*(double_enter)='\0';
				//subtitle_text = prune_string(subtitle_text);

				end_time = convert_pts_to_ms(ctx->packet.pts, ctx->format_ctx->streams[ctx->video_stream_id]->time_base);
				if(prev_subtitle_text)
				{
					//TODO: Encode text with highest confidence
					dist = edit_distance(subtitle_text, prev_subtitle_text, strlen(subtitle_text), strlen(prev_subtitle_text));

					if(dist > (0.2 * fmin(strlen(subtitle_text), strlen(prev_subtitle_text))))
					{
						add_cc_sub_text(ctx->dec_sub, prev_subtitle_text, begin_time, end_time, "", "BURN", CCX_ENC_UTF_8);
						encode_sub(enc_ctx, ctx->dec_sub);
						begin_time = end_time + 1;
					}
				}

				// if(ctx->conf_thresh > 0)
				// {
				// 	if(ctx->cur_conf >= ctx->prev_conf)
				// 	{
				// 		prev_subtitle_text = strdup(subtitle_text);
				// 		ctx->prev_conf = ctx->cur_conf;
				// 	}
				// }
				// else
				// {
				// 	prev_subtitle_text = strdup(subtitle_text);
				// }
				prev_subtitle_text = strdup(subtitle_text);
				prev_packet_pts = ctx->packet.pts;
			}
		}
		av_packet_unref(&ctx->packet);
	}

	add_cc_sub_text(ctx->dec_sub, prev_subtitle_text, begin_time, end_time, "", "BURN", CCX_ENC_UTF_8);
	encode_sub(enc_ctx, ctx->dec_sub);
	activity_progress(100,cur_sec/60,cur_sec%60);

}
예제 #18
0
파일: refine.c 프로젝트: yp/PIntron
bool
refine_borders(const char* const p,
					const size_t len_p,
					const char* const t,
					const size_t len_t,
					const unsigned int max_errs,
					size_t* out_offset_p,
					size_t* out_offset_t1,
					size_t* out_offset_t2,
					unsigned int* out_edit_distance) {
  const size_t t_win= MIN(len_p+max_errs, len_t);
  const unsigned int* Mp= edit_distance(t, t_win, p, len_p);
  const char* const rt= reverse(t, len_t);
  const char* const rp= reverse(p, len_p);
  const unsigned int* Ms= edit_distance(rt, t_win, rp, len_p);

  unsigned int* const min_pp= NPALLOC(unsigned int, len_p+1);
  unsigned int* const min_sp= NPALLOC(unsigned int, len_p+1);
  unsigned int* const min_pos_pp= NPALLOC(unsigned int, len_p+1);
  unsigned int* const min_pos_sp= NPALLOC(unsigned int, len_p+1);

  min_pp[0]= 0;
  min_pos_pp[0]= 0;
  size_t pos= t_win+1;
  for (size_t i= 0; i<len_p; ++i) {
	 min_pp[i+1]= Mp[pos];
	 min_pos_pp[i+1]= 0;
	 for (size_t j= 0; j<t_win; ++j) {
		++pos;
		if (min_pp[i+1]>Mp[pos]) {
		  min_pp[i+1]= Mp[pos];
		  min_pos_pp[i+1]= j+1;
		}
	 }
	 ++pos;
  }
  min_sp[0]= 0;
  min_pos_sp[0]= 0;
  pos= t_win+1;
  for (size_t i= 0; i<len_p; ++i) {
	 min_sp[i+1]= Ms[pos];
	 min_pos_sp[i+1]= 0;
	 for (size_t j= 0; j<t_win; ++j) {
		++pos;
		if (min_sp[i+1]>Ms[pos]) {
		  min_sp[i+1]= Ms[pos];
		  min_pos_sp[i+1]= j+1;
		}
	 }
	 ++pos;
  }

  size_t off_p= 0;
  size_t off_t1= min_pos_pp[0];
  size_t off_t2= min_pos_sp[len_p];
  unsigned int min= min_pp[0]+min_sp[len_p];
  int best_burset_freq= getBursetFrequency_adaptor(t, off_t1, len_t-off_t2);
  for (size_t i= 1; i<=len_p; ++i) {
	 const int curr_burset_freq= getBursetFrequency_adaptor(t, min_pos_pp[i],
																			  len_t-min_pos_sp[len_p-i]);
	 const unsigned int curr= min_pp[i]+min_sp[len_p-i];
	 if ((min>curr) ||
		  ((min==curr) && (curr_burset_freq>best_burset_freq))) {
		min= curr;
		off_p= i;
		off_t1= min_pos_pp[i];
		off_t2= min_pos_sp[len_p-i];
		best_burset_freq= curr_burset_freq;
	 }
  }
  *out_offset_p= off_p;
  *out_offset_t1= off_t1;
  *out_offset_t2= len_t-off_t2;
  *out_edit_distance= min;
  pfree(Mp);
  pfree(rt);
  pfree(rp);
  pfree(Ms);
  pfree(min_pp);
  pfree(min_pos_pp);
  pfree(min_sp);
  pfree(min_pos_sp);
  return MAX(0, min)<=max_errs;
}
예제 #19
0
void lc3_run_test_case(lc3_test& test, const std::string& filename, int seed)
{
    lc3_state state;

    // Preliminary stuff
    if (seed != -1) srand(seed);
    lc3_init(state, test.randomize, test.randomize);
    if (test.true_traps) lc3_set_true_traps(state, 1);
    if (test.interrupt_enabled) state.interrupt_enabled = 1;
    bool disable_plugins = test.disable_plugins;
    state.max_stack_size = 0;
    state.max_call_stack_size = -1;
    state.in_lc3test = true;

    try
    {
        LC3AssembleOptions options;
        options.multiple_errors = false;
        options.warnings_as_errors = false;
        options.process_debug_comments = false;
        options.enable_warnings = false;
        options.disable_plugins = disable_plugins;
        lc3_assemble(state, filename, options);
    }
    catch (LC3AssembleException e)
    {
        throw e.what();
    }


    std::stringstream* newinput = new std::stringstream();

    // Set up test environment
    for (unsigned int i = 0; i < test.input.size(); i++)
    {
        lc3_test_input& input = test.input[i];
        int value_calc;
        int address_calc = 0;
        unsigned short effective_address;

        ///TODO flip the condition here so that if new types are added you don't have to check for it here...
        if (input.type != TEST_IO && input.type != TEST_REGISTER && input.type != TEST_PC && input.type != TEST_SUBROUTINE &&
            lc3_calculate(state, input.address, address_calc) == -1)
            throw "An address expression " + input.address + " was not formed correctly.";
        else if (input.type == TEST_REGISTER)
        {
            if (input.address.size() != 2)
                throw "Register format is RX where x is between 0-7 found: " + input.address;

            address_calc = input.address[1] - '0';
            if (address_calc > 7 || address_calc < 0)
                throw "Invalid register " + input.address;
        }
        else
            lc3_calculate(state, input.address, address_calc);

        effective_address = (unsigned short) address_calc;

        switch (input.type)
        {
            case TEST_VALUE:
                if (lc3_calculate(state, input.value, value_calc))
                    throw "<in test-value> A value expression " + input.value + " was malformed.";
                state.mem[effective_address] = (short) value_calc;
                break;
            case TEST_REGISTER:
                if (lc3_calculate(state, input.registerval, value_calc))
                    throw "<in test-register> A value expression " + input.registerval + " was malformed.";
                state.regs[effective_address] = (short) value_calc;
                break;
            case TEST_PC:
                if (lc3_calculate(state, input.pcval, value_calc))
                    throw "<in test-pc> A value expression " + input.pcval + " was malformed.";
                state.pc = (unsigned short) value_calc;
                break;
            case TEST_POINTER:
                if (lc3_calculate(state, input.pointer, value_calc))
                    throw "<in test-pointer> An expression was " + input.pointer + " malformed.";
                state.mem[(unsigned short) state.mem[effective_address]] = (short) value_calc;
                break;
            case TEST_STRING:
                for (unsigned int j = 0; j < input.text.size(); j++)
                    state.mem[state.mem[effective_address] + j] = input.text[j];
                state.mem[(unsigned short) (state.mem[effective_address] + input.text.size())] = 0;
                break;
            case TEST_ARRAY:
                for (unsigned int j = 0; j < input.array.size(); j++)
                {
                    if (lc3_calculate(state, input.array[j], value_calc))
                        throw "<in test-array> An expression was " + input.array[j] + " malformed.";
                    state.mem[(unsigned short) (state.mem[effective_address] + j)] = (short) value_calc;
                }
                break;
            case TEST_IO:
                newinput->str(input.io);
                break;
            case TEST_SUBROUTINE:
                break;
            default:
                throw "Unknown test type";
        }

        if (input.type == TEST_SUBROUTINE)
        {
            lc3_subr_input& subr = input.subroutine;
            int pc;
            int r7;
            int r6;
            int r5;
            if (lc3_calculate(state, subr.name, pc) == -1)
                throw "<in test-subr> invalid subroutine name given " + subr.name;
            if (lc3_calculate(state, subr.stack, r6) == -1)
                throw "<in test-subr> stack expression was malformed " + subr.stack;
            if (lc3_calculate(state, subr.r7, r7) == -1)
                throw "<in test-subr> r7 expression was malformed " + subr.r7;
            if (lc3_calculate(state, subr.r5, r5) == -1)
                throw "<in test-subr> r5 expression was malformed " + subr.r5;

            state.pc = (unsigned short) pc;
            state.regs[6] = (unsigned short)(r6 - subr.params.size());
            state.regs[7] = (unsigned short) r7;
            state.regs[5] = (unsigned short) r5;
            state.mem[state.regs[7]] = 0xF025;

            for (unsigned int j = 0; j < subr.params.size(); j++)
            {
                if (lc3_calculate(state, subr.params[j], value_calc))
                    throw "<in test-subr> param expression " + subr.params[j] + " was malformed.";
                state.mem[(unsigned short)state.regs[6] + j] = (short) value_calc;
            }

            // This fixes the issue in which a subroutine is being tested, but it makes calls to other subroutines who takes a
            // different number of parameters than the subroutine under test.
            // If the file uses subroutine annotations then overwrite it.
            for (const auto& info : subr.subroutines)
            {
                int address = 0;
                if (lc3_calculate(state, info.name, address) == -1)
                    throw "<in test-subr> invalid subroutine name given " + info.name;

                lc3_subroutine_info test_info = info;
                test_info.address = (unsigned short) address;
                state.subroutines[(unsigned short)address] = test_info;
            }
        }
    }

    state.input = newinput;
    // Setup output capture device
    std::stringstream* newoutput = new std::stringstream();
    state.output = newoutput;
    std::stringstream* newwarning = new std::stringstream();
    state.warning = newwarning;

    if (test.has_max_executions)
    {
        unsigned long i = 0;
        // Do this num times or until halted.
        while (i < test.max_executions && !state.halted)
        {
            //printf("%04x: %s (%x)\n", state.pc, lc3_disassemble(state, state.mem[state.pc]).c_str(), (unsigned short)state.mem[state.pc]);
                /*printf("R0 %6d|x%04x\tR1 %6d|x%04x\tR2 %6d|x%04x\tR3 %6d|x%04x\nR4 %6d|x%04x\tR5 %6d|x%04x\tR6 %6d|x%04x\tR7 %6d|x%04x\nCC: %s\tPC: %04x\n\n",
                       state.regs[0], (unsigned short)state.regs[0], state.regs[1], (unsigned short)state.regs[1], state.regs[2], (unsigned short)state.regs[2],
                       state.regs[3], (unsigned short)state.regs[3], state.regs[4], (unsigned short)state.regs[4], state.regs[5], (unsigned short)state.regs[5],
                       state.regs[6], (unsigned short)state.regs[6], state.regs[7], (unsigned short)state.regs[7], (state.n ? "N" : (state.z ? "Z" : "P")),
                       (unsigned short) state.pc);*/
            // Step one instruction
            lc3_step(state);
            // Increment instruction count
            i++;
        }
        //lc3_run(state, test.max_executions);
    }
    else
        lc3_run(state);

    // Fill in the output values
    test.has_halted = state.halted;
    test.executions = state.executions;
    test.warnings = state.warnings;
    test.warning = newwarning->str();

    bool test_passed = true;
    unsigned int test_points = 0;
    unsigned int test_max_points = 0;
    // Check test environment
    for (unsigned int i = 0; i < test.output.size(); i++)
    {
        std::stringstream expected;
        std::stringstream actual;

        lc3_test_output& output = test.output[i];
        int value_calc;
        short short_cmp;
        int address_calc = 0;
        unsigned short effective_address;
        std::string str;
        std::vector<short> arrayexpected;
        std::vector<short> arrayactual;

        if (output.type != TEST_IO && output.type != TEST_REGISTER && output.type != TEST_PC && lc3_calculate(state, output.address, address_calc) == -1)
            throw "An address expression " + output.address + " was not formed correctly.";
        else if (output.type == TEST_REGISTER)
        {
            address_calc = output.address[1] - '0';
            if (address_calc > 7)
                throw "Invalid register " + output.address;
        }
        effective_address = (unsigned short) address_calc;

        output.passed = true;
        output.earned = 0;
        switch (output.type)
        {
            case TEST_VALUE:
                if (lc3_calculate(state, output.value, value_calc))
                    throw "<in test-value> An expression " + output.value + " was malformed.";

                short_cmp = (short) value_calc;
                output.passed = lc3_test_check(output, &state.mem[effective_address], &short_cmp);

                actual << state.mem[effective_address];
                expected << short_cmp;
                break;
            case TEST_REGISTER:
                if (lc3_calculate(state, output.registerval, value_calc))
                    throw "<in test-register> An expression " + output.registerval + " was malformed.";

                short_cmp = (short) value_calc;
                output.passed = lc3_test_check(output, &state.regs[effective_address], &short_cmp);

                actual << state.regs[effective_address];
                expected << short_cmp;
                break;
            case TEST_PC:
                if (lc3_calculate(state, output.pcval, value_calc))
                    throw "<in test-pc> An expression " + output.pcval + " was malformed.";

                short_cmp = (short) value_calc;
                output.passed = lc3_test_check(output, &state.pc, &short_cmp);

                actual << state.pc;
                expected << short_cmp;

                break;
            case TEST_POINTER:
                if (lc3_calculate(state, output.pointer, value_calc))
                    throw "<in test-pointer> An expression " + output.pointer + " was malformed.";

                short_cmp = (short) value_calc;
                output.passed = lc3_test_check(output, &state.mem[(unsigned short)state.mem[effective_address]], &short_cmp);

                actual << state.mem[(unsigned short)state.mem[effective_address]];
                expected << short_cmp;

                break;
            case TEST_STRING:
                value_calc = (unsigned short)state.mem[effective_address];
                short_cmp = state.mem[(unsigned short)value_calc];

                while(short_cmp > 0 && short_cmp <= 255)
                {
                    actual.put((char) short_cmp);
                    value_calc++;
                    short_cmp = state.mem[(unsigned short)value_calc];
                }

                str = actual.str();
                output.passed = lc3_test_check(output, &str, &output.text);
                expected << output.text;
                break;
            case TEST_ARRAY:
                for (unsigned int j = 0; j < output.array.size(); j++)
                {
                    if (lc3_calculate(state, output.array[j], value_calc))
                        throw "<in test-array> An expression " + output.array[j] + " was malformed.";

                    arrayexpected.push_back(state.mem[(unsigned short)(state.mem[effective_address] + j)]);
                    arrayactual.push_back((short)value_calc);

                    actual << state.mem[(unsigned short)(state.mem[effective_address] + j)] << " ";
                    expected << (short)value_calc << " ";
                }

                output.passed = lc3_test_check(output, &arrayactual, &arrayexpected);
                break;
            case TEST_IO:
                str = newoutput->str();
                output.passed = lc3_test_check(output, &str, &output.io);
                actual << str;
                expected << output.io;
                break;
            case TEST_SUBROUTINE:
                break;
            default:
                throw "Unknown test type";
        }

        if (output.type != TEST_SUBROUTINE)
        {
            if (output.passed)
                output.earned = output.points;
        }

        if (output.type == TEST_SUBROUTINE)
        {
            std::stringstream extra;
            lc3_subr_output& subr = output.subroutine;

            std::vector<short> expected_stack;
            std::vector<short> actual_stack;

            std::vector<short> locals;
            std::vector<short> params;
            for (int j = (int)subr.locals.size() - 1; j >= 0; j--)
            {
                if (lc3_calculate(state, subr.locals[j], value_calc))
                    throw "<in test-subr> A local variable expression " + subr.locals[i] + "was malformed.";

                expected_stack.push_back((short)value_calc);
                locals.push_back((short) value_calc);
            }

            int r7;
            int r6;
            int r5;
            int answer;
            if (lc3_calculate(state, subr.stack, r6) == -1)
                throw "<in test-subr> stack expression " + subr.stack + " was malformed";
            if (lc3_calculate(state, subr.r7, r7) == -1)
                throw "<in test-subr> r7 expression " + subr.r7 + " was malformed";
            if (lc3_calculate(state, subr.r5, r5) == -1)
                throw "<in test-subr> r5 expression " + subr.r5 + " was malformed";
            if (lc3_calculate(state, subr.answer, answer) == -1)
                throw "<in test-subr> answer expression " + subr.answer + " was malformed";

            expected_stack.push_back((short)r5);
            expected_stack.push_back((short)r7);
            expected_stack.push_back((short)answer);

            for (unsigned int j = 0; j < subr.params.size(); j++)
            {
                if (lc3_calculate(state, subr.params[j], value_calc))
                    throw "<in test-subr> A param expression " + subr.params[j] + " was malformed.";
                expected_stack.push_back((short)value_calc);
                params.push_back((short) value_calc);
            }

            // Code to get the students stack frame
            unsigned short actual_r6 = (unsigned short) r6;
            if (state.first_level_calls.size() >= 1)
            {
                const auto& call_info = state.first_level_calls[0];
                unsigned short subr_location = call_info.address;
                if (state.subroutines.find(subr_location) == state.subroutines.end())
                {
                    extra << "      [WARNING] Could not determine number of parameters for subroutine " <<
                        lc3_sym_rev_lookup(state, subr_location) << " at address " <<
                        std::hex << "0x" << subr_location << "\n";
                }
                unsigned short start = call_info.r6 + call_info.params.size();
                // Screams...
                if (start >= actual_r6)
                    extra << "      [WARNING] Could not get students stack frame.\n"
                             "      Is the student managing the stack correctly?\n";
                else
                    actual_stack.assign(state.mem + start, state.mem + actual_r6);
            }
            else if (state.first_level_calls.empty())
            {
                int num_params = subr.params.size();
                // Get at least the parameters student could probably not save anything...
                actual_stack.assign(state.mem + (actual_r6 - num_params), state.mem + actual_r6);
                // Get additional addresses modified
                unsigned short start = actual_r6 - num_params - 1;
                while (state.memory_ops.find(start) != state.memory_ops.end())
                {
                    if (!state.memory_ops[start].writes) break;
                    actual_stack.insert(actual_stack.begin(), state.mem[start]);
                    start--;
                }
            }

            for (unsigned int j = 0; j < expected_stack.size(); j++)
                expected << std::hex << "0x" << expected_stack[j] << " ";
            expected << " r5: " << std::hex << "0x" << (short)r5 <<
                        " r6: " << std::hex << "0x" << (actual_r6 - subr.params.size() - 1) <<
                        " r7: " << std::hex << "0x" << (short)(r7 + 1);


            for (unsigned int j = 0; j < actual_stack.size(); j++)
                actual << std::hex << "0x" << actual_stack[j] << " ";
            actual << " r5: " << std::hex << "0x" << state.regs[5] <<
                      " r6: " << std::hex << "0x" << state.regs[6] <<
                      " r7: " << std::hex << "0x" << state.regs[7];

            // now that I have all information available time for some checks.
            std::map<short, int> actual_stack_map;
            for (unsigned int j = 0; j < actual_stack.size(); j++)
                actual_stack_map[actual_stack[j]] += 1;

            int points = 0;
            // If they get something wrong then it will also be wrong in edit distance
            // so cut some slack if you get a value wrong.
            int ed_forgiveness = 0;

            if (actual_stack_map[(short)answer] > 0)
            {
                actual_stack_map[(short)answer] -= 1;
                points += subr.points_answer;
                extra << CHECK << ANSWER_FOUND << " +" << subr.points_answer << ".\n";
            }
            else
            {
                ed_forgiveness++;
                extra << MISS << ANSWER_FOUND << " -" << subr.points_answer << ".\n";
            }

            if (state.regs[6] == (short)(actual_r6 - subr.params.size() - 1))
            {
                points += subr.points_r6;
                extra << CHECK << R6_FOUND << " +" << subr.points_r6 << ".\n";
            }
            else
            {
                extra << MISS << R6_FOUND << " -" << subr.points_r6 << ".\n";
            }

            if (actual_stack_map[(short)r7] > 0 && state.regs[7] == (short)(r7+1))
            {
                actual_stack_map[(short)r7] -= 1;
                points += subr.points_r7;
                extra << CHECK << R7_FOUND << " +" << subr.points_r7 << ".\n";
            }
            else
            {
                // Don't count if just r7 was clobbered
                if (actual_stack_map[(short)r7] <= 0)
                    ed_forgiveness++;
                extra << MISS << R7_FOUND << " -" << subr.points_r7 << ".\n";
            }

            if (actual_stack_map[(short)r5] > 0 && state.regs[5] == (short)r5)
            {
                actual_stack_map[(short)r5] -= 1;
                points += subr.points_r5;
                extra << CHECK << R5_FOUND << " +" << subr.points_r5 << ".\n";
            }
            else
            {
                if (actual_stack_map[(short)r5] <= 0)
                    ed_forgiveness++;
                extra << MISS << R5_FOUND << " -" << subr.points_r5 << ".\n";
            }

            for (unsigned int j = 0; j < params.size(); j++)
            {
                if (actual_stack_map[params[j]] > 0)
                {
                    actual_stack_map[params[j]] -= 1;
                    points += subr.points_params;
                    extra << CHECK << params[j] << " " << PARAM_FOUND << " +" << subr.points_params << ".\n";
                }
                else
                {
                    ed_forgiveness++;
                    extra << MISS << params[j] << " " << PARAM_FOUND << " -" << subr.points_params << ".\n";
                }
            }

            bool all_locals_wrong = true;
            for (unsigned int j = 0; j < locals.size(); j++)
            {
                if (actual_stack_map[locals[j]] > 0)
                {
                    actual_stack_map[locals[j]] -= 1;
                    points += subr.points_locals;
                    all_locals_wrong = false;
                    extra << CHECK << locals[j] << " " << LOCAL_FOUND << " +" << subr.points_locals << ".\n";
                }
                else
                {
                    ed_forgiveness++;
                    extra << MISS << locals[j] << " " << LOCAL_FOUND << " -" << subr.points_locals << ".\n";
                }
            }

            // Subroutine calls check.
            std::set<lc3_subroutine_call_info, lc3_subroutine_call_info_cmp> actual_calls(state.first_level_calls.begin(), state.first_level_calls.end());
            std::set<lc3_subroutine_call_info, lc3_subroutine_call_info_cmp> expected_calls;
            for (const auto& expected_call : subr.calls)
            {
                lc3_subroutine_call_info info;
                int addr = lc3_sym_lookup(state, expected_call.name);
                if (addr == -1)
                    throw "Invalid subroutine name given in <call> " + expected_call.name;
                for (unsigned int i = 0; i < expected_call.params.size(); i++)
                {
                    int param;
                    if (lc3_calculate(state, expected_call.params[i], param) == -1)
                        throw "<in test-subr/call> param expression " + expected_call.params[i] + " was malformed";
                    info.params.push_back(param);
                }
                info.address = addr;
                info.r6 = 0;
                expected_calls.insert(info);
            }

            for (const auto& call : expected_calls)
            {
                std::stringstream call_name;
                call_name << lc3_sym_rev_lookup(state, call.address) << "(";
                if (state.subroutines.find(call.address) == state.subroutines.end())
                    call_name << "?";
                for (unsigned int i = 0; i < call.params.size(); i++)
                {

                    call_name << std::hex << "0x" << call.params[i];
                    if (i != call.params.size() - 1)
                        call_name << ",";
                }
                call_name << ")";

                if (actual_calls.find(call) != actual_calls.end())
                {
                    extra << CHECK << "Call " << call_name.str() << " made correctly.\n";
                    points += subr.points_calls;
                }
                else
                {
                    extra << MISS << "Call " << call_name.str() << " was not made.\n";
                }
            }
            for (const auto& call : actual_calls)
            {
                std::stringstream call_name;

                std::string name = lc3_sym_rev_lookup(state, call.address);
                if (name.empty())
                    call_name << "0x" << std::hex << call.address << "(";
                else
                    call_name << name << "(";
                if (state.subroutines.find(call.address) == state.subroutines.end())
                    call_name << "?";
                for (unsigned int i = 0; i < call.params.size(); i++)
                {

                    call_name << std::hex << "0x" << call.params[i];
                    if (i != call.params.size() - 1)
                        call_name << ",";
                }
                call_name << ")";

                if (expected_calls.find(call) == expected_calls.end())
                {
                    extra << MISS << "Unexpected Call " << call_name.str() << " made.\n";
                }
            }

            // Read answer check sigh...
            if (subr.points_read_answer > 0)
            {
                for (const auto& call : actual_calls)
                {
                    if (expected_calls.find(call) != expected_calls.end() && !call.params.empty())
                    {
                        if (state.memory_ops[call.r6 - 1].reads > 0)
                        {
                            extra << CHECK << "Read answer from stack.\n";
                            points += subr.points_read_answer;
                        }
                        else
                            extra << MISS << "Did not read answer from stack.\n";
                    }
                }
            }

            // If all local variables are wrong then it can be argued that they was saving registers
            // And forgot to save locals...
            if (all_locals_wrong)
            {
                // Bro do you even calling convention
                if (actual_stack.size() > subr.params.size() + 3)
                    // Truncate stack to last num_params + 3 elements the stuff we care about (don't do expected since ed forgiveness handles it).
                    actual_stack.erase(actual_stack.begin(), actual_stack.begin() + (actual_stack.size() - subr.params.size() - 3));
                if (!subr.locals.empty())
                    extra << "      All locals were not found, so locals aren't included in structure check.\n";
            }
            else
            {
                if (actual_stack.size() > expected_stack.size())
                    expected_stack.insert(expected_stack.begin(), actual_stack.begin(), actual_stack.begin() + (actual_stack.size() - expected_stack.size()));
            }

            int ed_grade = edit_distance(actual_stack, expected_stack);
            points -= (ed_grade - ed_forgiveness) * subr.deductions_edist;
            int mistakes = ed_grade - ed_forgiveness;


            if (mistakes == 0)
                extra << "      Found no structural mistakes in the stack.  No changes needed.\n";
            else
                extra << "      Found " << mistakes << " structural mistakes in stack -" << subr.deductions_edist * mistakes << ".\n";

            output.passed = (ed_grade == 0) && (ed_forgiveness == 0);
            output.extra_output += extra.str();
            output.earned = points;
        }

        test_passed = test_passed && output.passed;
        test_points += output.earned;
        test_max_points += output.points;

        output.expected = expected.str();
        output.actual = actual.str();
    }

    // Tear down
    delete state.input;
    delete state.output;
    delete state.warning;

    test.passed = test_passed;
    test.points = test_points;
    test.max_points = test_max_points;
}
예제 #20
0
    int
    test() {
        std::string s1, s2;
        s1 = "duckduckgo"; s2 = "duckduckgoose";
        cerr<<"Edit Distance("<<s1<<", "<<s2<<"): "<<edit_distance(s1, s2)<<endl;
        assert(edit_distance(s1, s2) == 3);

        s1 = "duckduckgoose"; s2 = "duckduckgo";
        cerr<<"Edit Distance("<<s1<<", "<<s2<<"): "<<edit_distance(s1, s2)<<endl;
        assert(edit_distance(s1, s2) == 3);

        s1 = "duckduckgo.com"; s2 = "duckduckgoose";
        cerr<<"Edit Distance("<<s1<<", "<<s2<<"): "<<edit_distance(s1, s2)<<endl;
        assert(edit_distance(s1, s2) == 4);

        s1 = "duckduckgoose"; s2 = "duckduckgo.com";
        cerr<<"Edit Distance("<<s1<<", "<<s2<<"): "<<edit_distance(s1, s2)<<endl;
        assert(edit_distance(s1, s2) == 4);

        s1 = "duckduckgo.com"; s2 = "dukgo.com";
        cerr<<"Edit Distance("<<s1<<", "<<s2<<"): "<<edit_distance(s1, s2)<<endl;
        assert(edit_distance(s1, s2) == 5);

        s1 = "luck"; s2 = "duck";
        cerr<<"Edit Distance("<<s1<<", "<<s2<<"): "<<edit_distance(s1, s2)<<endl;
        assert(edit_distance(s1, s2) == 1);

        s1 = "deer"; s2 = "duck";
        cerr<<"Edit Distance("<<s1<<", "<<s2<<"): "<<edit_distance(s1, s2)<<endl;
        assert(edit_distance(s1, s2) == 3);

        s1 = "elephant"; s2 = "duck";
        cerr<<"Edit Distance("<<s1<<", "<<s2<<"): "<<edit_distance(s1, s2)<<endl;
        assert(edit_distance(s1, s2) == 8);

        s1 = "duck"; s2 = "elephant";
        cerr<<"Edit Distance("<<s1<<", "<<s2<<"): "<<edit_distance(s1, s2)<<endl;
        assert(edit_distance(s1, s2) == 8);

        s1 = "abracadabra magic! magic! magic!"; s2 = "the great Hoodini";
        int x = 0;
        clock_t start = clock();
        const int ntimes = 50000;
        for (int i = 0; i < ntimes; ++i) {
            x = edit_distance(s1, s2);
        }
        clock_t end = clock();
        double sec_diff = (double)(end - start) / CLOCKS_PER_SEC;

        cerr<<"Edit Distance("<<s1<<", "<<s2<<"): "<<x<<endl;
        cerr<<"Time to compute "<<ntimes<<" times: "<<sec_diff<<" second. sec/compare: "<<sec_diff/ntimes<<endl;
        return 0;
    }
inline size_t EditDistance(const Sequence& s1, const Sequence& s2) {
	return edit_distance(s1.str(), s2.str());
}