searchsrtree.c
来自「R 树」· C语言 代码 · 共 325 行
C
325 行
/* * searchSRTree.c * Copyright (C) 1997 Norio Katayama * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, * MA 02111-1307, USA * * 10/14/96 katayama@rd.nacsis.ac.jp * $Id: searchSRTree.c,v 1.4 1997/06/02 09:35:59 katayama Exp $ */#include <math.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include "HnSRTree.h"#include "record.h"static void searchNeighbors(int dimension, const char *dataFileName, const char *treeFileName, int maxCount, int debug, int verify, int neighbors);static void searchRange(int dimension, const char *dataFileName, const char *treeFileName, int maxCount, int debug, int verify, double width);intmain(int argc, char *argv[]){ int dimension; int maxCount, debug, verify; int neighbors; double width; char *treeFileName, *dataFileName; int c, errflag; extern int optind; extern char *optarg; maxCount = -1; debug = 0; neighbors = 1; width = 0; verify = 0; errflag = 0; while((c = getopt(argc, argv, "c:dn:vw:")) != EOF) { switch(c) { case 'c': maxCount = atoi(optarg); break; case 'd': debug = 1; break; case 'n': neighbors = atoi(optarg); break; case 'v': verify = 1; break; case 'w': width = atof(optarg); break; case '?': errflag = 1; break; } } if(errflag || optind != argc - 3) { fprintf(stderr, "Usage: %s [options] dimension datafile treefile\n" "Options\n" " -c count set the count of data\n" " -d turn on the debug mode\n" " -n neighbors set the number of neighbors\n" " -v verify verify data existence\n" " -w width set the width of the search range\n", argv[0]); return 1; } if(neighbors > 1 && width > 0) { fprintf(stderr, "%s: cannot set both `-n' and `-w' options.\n", argv[0]); return 1; } dimension = atoi(argv[optind]); dataFileName = argv[optind + 1]; treeFileName = argv[optind + 2]; if(width == 0) searchNeighbors(dimension, dataFileName, treeFileName, maxCount, debug, verify, neighbors); else searchRange(dimension, dataFileName, treeFileName, maxCount, debug, verify, width); return 0;}static voidsearchNeighbors(int dimension, const char *dataFileName, const char *treeFileName, int maxCount, int debug, int verify, int neighbors){ HnSRTree *srtree; HnSRTreeRecord *hits; int numHits; RecordPoint recordPoint; RecordData recordData; FILE *fp; int i, count; char buffer[BUFFER_SIZE]; if((srtree = HnSRTreeOpen(treeFileName)) == NULL) { perror(treeFileName); exit(1); } if(debug) HnSRTreeSetDebug(srtree, 1); if(HnSRTreeGetDimension(srtree) != dimension) { fprintf(stderr, "Mismatch in dimensions. " "The dimension of the tree is %d.\n", HnSRTreeGetDimension(srtree)); exit(1); } if((fp = fopen(dataFileName, "r")) == NULL) { perror(dataFileName); exit(1); } count = 0; while((maxCount < 0 || count < maxCount) && fgets(buffer, sizeof(buffer), fp) != NULL) { if(buffer[0] == '#' || buffer[0] == '\n') continue; getRecord(buffer, dimension, &recordPoint, &recordData); if(includesNANorINF(&recordPoint)) continue; /* search data */ printf("Searching %s\n", (char *)pointToString(&recordPoint)); HnSRTreeGetNeighbors(srtree, recordPoint.coords, neighbors, &hits, &numHits); for(i=0; i<numHits; i++) { char *fname = ((RecordData *)hits[i].data)->fname; double distance; int j; double w, sum; sum = 0; for(j=0; j<dimension; j++) { w = recordPoint.coords[j] - hits[i].coords[j]; sum += w * w; } distance = sqrt(sum); printf("%s: %g\n", fname, distance); } printf("\n"); if(verify) { int found = 0; for(i=0; i<numHits; i++) { int equal = 1; int j; for(j=0; j<dimension; j++) { if(recordPoint.coords[j] != hits[i].coords[j]) { equal = 0; break; } } if(equal && memcmp(&recordData, hits[i].data, sizeof(RecordData)) == 0) found = 1; } if(!found) { fprintf(stderr, "data is not found.\n"); exit(1); } } count ++; } fclose(fp); HnSRTreeClose(srtree);}static voidsearchRange(int dimension, const char *dataFileName, const char *treeFileName, int maxCount, int debug, int verify, double width){ HnSRTree *srtree; HnSRTreeRange *ranges; HnSRTreeRecord *record; RecordPoint recordPoint; RecordData recordData; FILE *fp; int i, count; char buffer[BUFFER_SIZE]; /* for verify */ int found = 0; if((ranges = (HnSRTreeRange *) malloc(sizeof(HnSRTreeRange) * dimension)) == NULL) { perror("malloc"); exit(1); } if((srtree = HnSRTreeOpen(treeFileName)) == NULL) { perror(treeFileName); exit(1); } if(debug) HnSRTreeSetDebug(srtree, 1); if(HnSRTreeGetDimension(srtree) != dimension) { fprintf(stderr, "Mismatch in dimensions. " "The dimension of the tree is %d.\n", HnSRTreeGetDimension(srtree)); exit(1); } if((fp = fopen(dataFileName, "r")) == NULL) { perror(dataFileName); exit(1); } count = 0; while((maxCount < 0 || count < maxCount) && fgets(buffer, sizeof(buffer), fp) != NULL) { if(buffer[0] == '#' || buffer[0] == '\n') continue; getRecord(buffer, dimension, &recordPoint, &recordData); if(includesNANorINF(&recordPoint)) continue; /* extend the rectangle by the given width */ for(i=0; i<dimension; i++) { double x = recordPoint.coords[i]; ranges[i].min = x - width / 2; ranges[i].max = x + width / 2; } if(verify) found = 0; /* search data */ printf("Searching %s\n", (char *)pointToString(&recordPoint)); HnSRTreeGetFirst(srtree, ranges, &record); while(record != NULL) { char *fname = ((RecordData *)record->data)->fname; printf("%s\n", fname); if(verify) { int equal = 1; int j; for(j=0; j<dimension; j++) { if(recordPoint.coords[j] != record->coords[j]) { equal = 0; break; } } if(equal && memcmp(&recordData, record->data, sizeof(RecordData)) == 0) found = 1; } HnSRTreeGetNext(srtree, &record); } printf("\n"); if(verify) { if(!found) { fprintf(stderr, "data is not found.\n"); exit(1); } } count ++; } fclose(fp); HnSRTreeClose(srtree);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?