|
Thread Rules 1. This is not a "do my homework for me" thread. If you have specific questions, ask, but don't post an assignment or homework problem and expect an exact solution. 2. No recruiting for your cockamamie projects (you won't replace facebook with 3 dudes you found on the internet and $20) 3. If you can't articulate why a language is bad, don't start slinging shit about it. Just remember that nothing is worse than making CSS IE6 compatible. 4. Use [code] tags to format code blocks. |
|
I have had to do this and here is how I did it:
First you want to cluster the data. Basically loop through all of your elements and any time you come to an element that is "far" from all other "captains" make that guy a captain. When you are done you will have some number of captains. Then assign everyone else to the nearest captain. Each captain should have a sorted list of elements where the closest elements come first and the furthest later. You can do this hierarchically and each level of hierarchy down you redefine far so that more and more elements are far.
When you want to find the nearest element you simply loop over all the captains and then find the nearest captain. Then loop over elements near that captain and find the nearest element. This gives you a pretty good answer that still might not be the best. Now you must loop over all the other captains. From those captains you can skip the vast majority of their elements based on this information.
T = Target B = Best so Far D = Best Captain (May not be best's Captain) C = Current Captain X = Elements in Current Captain
BT = Distance between Best and Target CD = Distance between Current Captain an Best Captain etc
First of all we know that CX < DX because otherwise those elements in C would have been put in D.
Sometimes we can skip the whole Captain:
if (BT + DT < CD/2) then we know that we can safely skip the Current Captain C because any element closer to T than B would have also been closer to D than C so it would not be in C.
If we cannot skip C altogether then we must traverse into hierarchically, or if it is a leaf node with a sorted list of elements we need only consider elements X such that:
CX > CT - BT
|
If you (OP) are looking for a way to find the closest element based on a given metric it seems that you have a pretty good algo. However, maybe what you actually want is different. I'd like to group my data to find clusters of similar results and then have the distance towards their centers (like what the previous poster suggested). It's area of research in machine learning: https://en.wikipedia.org/wiki/Cluster_analysis There are many algorithms and the classic ones are well implemented. They will handle million of records easily.
|
I've quickly checked some of Boost's source files and they use ifdef for Windows as expected. Is this how libraries like Boost achieve cross-platform solution?
|
Ok, I think I got around to finishing my irange and arange functions in C but I've run into a problem compiling them... I really forgot how to do that 
+ Show Spoiler [code] + //main.c #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include "arange.h" #include "irange.h"
int main(void) { int_range_t *int_range = irange(1, 5); char_range_t *char_range = arange('a', 'f');
puts("Int range:\n");
for (int i = 0; i < int_range->length; i++) { printf("%d", int_range->nums[i]); }
puts("Char range:\n");
for (int i = 0; i < char_range->length; i++) { printf("%c", char_range->chars[i]); }
free(int_range); free(char_range);
return 0; }
//arange.h #include <stdlib.h> #include <stdbool.h>
/* Definitions */ typedef struct char_range_s char_range_t;
/* Prototypes */ char_range_t *arange(char start, char end); bool is_valid_letter(char input);
//arange.c #include "arange.h"
typedef struct char_range_s { int length; char chars[]; } char_range_t;
/* * Function : arange * Arguments: char start - initial char, char end - final char * (if start > end the range will be in descending order, * only letters are supported) * Returns : char_range_t or NULL * Notes : The caller has to free the allocated memory */ char_range_t *arange(char start, char end) { if (!is_valid_letter(start) || !is_valid_letter(end)) { return NULL; }
char c; int istart = start - '0'; int iend = end - '0'; bool reverse = (iend < istart); int size = (reverse ? istart - iend : iend - istart) + 1; size_t mem = sizeof(char_range_t) + size * sizeof(char); char_range_t *range = malloc(mem);
if (range == NULL) { return NULL; }
range->length = size;
for (int i = 0; i < size; i += 1) { c = reverse ? istart - i : istart + i; range->chars[i] = c; }
return range; }
bool is_valid_letter(char input) { int val = input - '0';
if ((val >= 65 && val <= 90) || (val >= 97 && val <= 122)) { return true; }
return false; }
//irange.h #include <stdlib.h> #include <stdbool.h>
/* Definitions */ typedef struct int_range_s int_range_t;
/* Prototypes */ int_range_t *irange(int start, int end);
//irange.c #include "irange.h"
typedef struct int_range_s { int length; int nums[]; } int_range_t;
/* * Function : irange * Arguments: int start - initial int, int end - final int * (if start > end the range will be in descending order) * Returns : int_range_t or NULL * Notes : The caller has to free the allocated memory */ int_range_t *irange(int start, int end) { bool reverse = (end < start); int size = (reverse ? start - end : end - start) + 1; size_t mem = sizeof(int_range_t) + size * sizeof(int); int_range_t *range = malloc(mem);
if (range == NULL) { return NULL; }
range->length = size;
for (int i = 0; i < size; i += 1) { range->nums[i] = reverse ? start - i : start + i; }
return range; }
Now, when I try something like that:
gcc -Wall -g -std=c99 -o main main.c arange.c irange.c -lm
I get such errors:
main.c: In function ‘main’: main.c:14:34: error: dereferencing pointer to incomplete type for (int i = 0; i < int_range->length; i++) { ^ main.c:15:31: error: dereferencing pointer to incomplete type printf("%d", int_range->nums[i]); ^ main.c:20:35: error: dereferencing pointer to incomplete type for (int i = 0; i < char_range->length; i++) { ^ main.c:21:32: error: dereferencing pointer to incomplete type printf("%c", char_range->chars[i]); ^
It seems like something has gone wrong with the linking but I must say I'm lost... Should I move entire typedef struct definitions into header files?
Edit: Yeah, that solved it. And now I know that my program segfaults on char_range->length and I have no idea why
|
Yes, the struct has to be in the header file. I think about translating the "->" and "." into memory offsets in the machine code, this part of the job is done by the compiler, not the linker, so the compiler has to know about the concrete sizes of elements inside structs. It then needs the definition of the struct inside each file it compiles, so it needs to be in the header file that you're including everywhere you need a type.
|
Your issue is with conversion from char to int. You use
int val = input - '0';
But in C, chars are already integers from 0 to 255, so use them as such (don't substract '0').
Sometimes you'll see that code, but it has a different purpose. It converts the digits from 0 to 9 from ASCII code to ordinal.
Actually, 'A' is the same as 65 and you could write
if ((val >= 'A' && val <= 'Z') || (val >= 'a' && val <= 'z')) {
or better yet, use isalpha(input) from ctype.h
|
|
On May 08 2016 03:46 Wrath wrote: Google down? no
|
Damn you were too fast. It is working now again. Minutes ago I could not load anything, gmail / google / translator. All were giving errors. Not sure what was the issue.
|
Does anyone know a good book or program to practice troubleshooting with gdb? Preferably C++ oriented, but that doesn't really matter.
|
On May 08 2016 01:24 Hhanh00 wrote:Your issue is with conversion from char to int. You use int val = input - '0';
But in C, chars are already integers from 0 to 255, so use them as such (don't substract '0'). Sometimes you'll see that code, but it has a different purpose. It converts the digits from 0 to 9 from ASCII code to ordinal. Actually, 'A' is the same as 65 and you could write if ((val >= 'A' && val <= 'Z') || (val >= 'a' && val <= 'z')) {
or better yet, use isalpha(input) from ctype.h
Great. Thanks for that. But can I also do regular math on chars ('z' - 'a' for example)? Will the return type be integer?
I'll have to try it out as that would simplify the code for me greatly.
|
On May 08 2016 09:00 Manit0u wrote: Great. Thanks for that. But can I also do regular math on chars ('z' - 'a' for example)? Will the return type be integer?
I'll have to try it out as that would simplify the code for me greatly.
Yeah you can, the type will be char but `int x = 'z' - 'a'` will compile just fine and work as you expect it to so it's a pretty academic point.
edit: I'm wrong, see below
|
On May 08 2016 09:06 Cyx. wrote:Show nested quote +On May 08 2016 09:00 Manit0u wrote: Great. Thanks for that. But can I also do regular math on chars ('z' - 'a' for example)? Will the return type be integer?
I'll have to try it out as that would simplify the code for me greatly.
Yeah you can, the type will be char but `int x = 'z' - 'a'` will compile just fine and work as you expect it to so it's a pretty academic point. No. The type of 'a' - 'z' is int. What happens here is called integer promotion.
|
On May 08 2016 16:21 Biolunar wrote: No. The type of 'a' - 'z' is int. What happens here is called integer promotion. I stand corrected, I read the relevant sections of the standard and you're definitely right.
|
On May 01 2016 03:10 amazingxkcd wrote:Show nested quote +On May 01 2016 02:21 Artesimo wrote:I am forced to use netbeans for a number of reasons. I am just baffled how "incredible" it is, given the fact that we are forced to work with it in some lectures. Right now I am just coding with gedit and giggle like a retard when I copy my code into netbeans and it just compiles even though it marks almost everything as wrong. It is better then the other way around  netbeans is fine but you have to spend time to set the IDE up right.
Even though I am late to the party: just no. Maybe it is somewhat fine for java, but for C++ Netbeans is a piece of shit that should have died a long time ago, yet it annoyingly finds its way onto pretty much any lab-computer in universities that runs a Unix system. I can't tell you how much of my time this thing wasted by either giving completely misleading warnings/error-messages or straight up messing shit up on his own. It believes c++11 is highly experimental and therefore you should always default to c++98, it is slow as hell, every default theme is probably the best example for poor visibility, it likes to waste your time and to break itself. Last semester I had to fix some linker settings multiple times and it somehow forgot the correct path to some of the standard-includes 2 times without me every changing anything that could have caused that. The only good thing I can say about Netbeans is the quick “fix imports”-function and the refactor-function and both you can get as an extension for pretty much any IDE that is somewhat up to date. By this time, whenever some assignment features programming on UNIX, I am praying that we are allowed to use our own machines instead of the lab because if notepad++ would feature a compiler, it would make a better IDE.
Netbeans is a crime against humanity.
|
Even for java, I prefer both intellij and eclipse. That said, eclipse's c support is absolutely awful. In fact, eclipse for anything non-java is a horrible experience, whereas pycharm and webstorm are both amazing. How is CLion?
|
On May 09 2016 09:08 Acrofales wrote: Even for java, I prefer both intellij and eclipse. That said, eclipse's c support is absolutely awful. In fact, eclipse for anything non-java is a horrible experience, whereas pycharm and webstorm are both amazing. How is CLion?
You can trial it yourself you know 
But seriously, I have yet to find Jetbrains product that wouldn't deliver.
And to anyone saying that Netbeans is good - have you ever tried to turn on whitespace visibility in it? Or trimming trailing whitespace for that matter?
|
On Windows, Dev Studio is the best. On MacOS, it's XCode obviously. On Linux, none of them are as good.
|
On May 09 2016 11:30 Hhanh00 wrote: On Windows, Dev Studio is the best. On MacOS, it's XCode obviously. On Linux, none of them are as good.
When you say Dev Studio do you mean Visual Studio? No one refers to Dev Studio at work..
|
|
|
|